"""
联盟分配算子
进行算子的转移退出
形成最终的联盟
输出联盟分配的结果和目标点位
"""
import random
import time

import pandas as pd
import copy
import itertools
import numpy as np
import math
import csv

from ai.const import *
from collections import Counter
from copy import deepcopy
from .situation import *
from .agent import *
from functools import reduce
from collections import Counter
from .infer_paras import *


class ALLIANCEAllocation(object):
    def __init__(self):
        self.operators = []  # 我方算子集合
        """
        类似operators的数据类型
        """
        self.mission = None  # 指挥意图 给mission的预留接口
        # self.situation = None  # 获取资源集合
        self.time = None  # 任务分配允许时间

        self.cities_num = None  # 夺控点数量
        self.cities = []  # 夺控点列表
        self.union = None
        self.our_cities = []
        self.last_enemies_cities = {}
        self.sort1_max_hex = None
        self.tank1 = None
        # self.efficiency = None  # 单个算子行为树效能值
        # self.addition = None  # 两个算子行为树对于完成任务的加成值
        self.efficiency = {}
        """(dict)
        {mission: {(sub_type, task): efficiency, (sub_type, task): efficiency ...}}
        """
        self.addition = {}
        """(dict)
        {mission:((sub_type, task), (sub_type, task)): addition, ((sub_type, task), (sub_type, task)): addition...}
        """
        self.paobing = None  # 炮兵obj_id列表
        self.attact_operator = None  # 存放进攻性算子 要清空
        self.defence_operator = None  # 存放防御性算子 要清空
        self.overall_operator = {}  # 每个联盟有的全局算子 {'artillery':[obj_id],'uav':[obj_id],'cruise':[obj_id]}
        self.bubing = None  # 步兵obj_id列表
        self.uav = None  # 无人机obj_id列表
        self.tank = None  # 坦克obj_id列表
        self.cruise = None  # 巡飞弹obj_id列表
        self.zc = None  # 战车obj_id列表
        self.max_union = None  #
        self.empty_union = None  # 存放没有基本兵力的联盟 [{'city':...},{}]
        self.rank_city_2 = None  # 第二次排序结果
        self.sort_1 = []  # 第1次排序结果夺控点坐标由近到远
        self.clear_mine_result = []  # 存放扫雷车分配情况[[city,obj_id],[city,obj_id],[city,obj_id]]

    def setup(self, agent):  # 初始化函数

        # cities = observation["cities"]
        for cities in agent.city_coord:
            self.cities.append(cities)
            self.last_enemies_cities.update({cities: -1})
        self.cities_num = len(agent.city_coord)  # 获取夺控点数量 根据夺控点数量确定联盟个数
        attack = './进攻.csv'
        defense = './防御.csv'
        full_attack = './完全进攻.csv'
        full_defense = './完全防御.csv'
        attack_efficiency, attack_addition = self.read(attack)
        defense_efficiency, defense_addition = self.read(defense)
        full_attack_efficiency, full_attack_addition = self.read(full_attack)
        full_defense_efficiency, full_defense_addition = self.read(full_defense)
        self.efficiency.update(
            {0: attack_efficiency, 1: defense_efficiency, 2: full_attack_efficiency, 3: full_attack_efficiency})
        self.addition.update(
            {0: attack_addition, 1: defense_addition, 2: full_attack_addition, 3: full_defense_addition})
        '''
        self.efficiency = {0: {(0, 0): 0.50, (0, 1): 0.38, (0, 2): 0.22, (1, 0): 0.30, (1, 1): 0.22, (1, 2): 0.14,
                               (2, 0): 0.21, (2, 1): 0.16, (2, 2): 0, (3, 0): 0.20, (3, 1): 0.15, (3, 2): 0.08,
                               (4, 0): 0.29, (4, 1): 0.21, (4, 2): 0.13, (5, 0): 0, (5, 1): 0, (5, 2): 0,
                               (7, 0): 0.14, (7, 1): 0.11, (7, 2): 0.08},
                           1: {(0, 0): 0.38, (0, 1): 0.50, (0, 2): 0.22, (1, 0): 0.22, (1, 1): 0.30, (1, 2): 0.15,
                               (2, 0): 0.16, (2, 1): 0.21, (2, 2): 0, (3, 0): 0.15, (3, 1): 0.20, (3, 2): 0.08,
                               (4, 0): 0.21, (4, 1): 0.29, (4, 2): 0.13, (5, 0): 0, (5, 1): 0, (5, 2): 0,
                               (7, 0): 0.11, (7, 1): 0.14, (7, 2): 0.08},
                           2: {(0, 0): 0.58, (0, 1): 0.41, (0, 2): 0.24, (1, 0): 0.36, (1, 1): 0.25, (1, 2): 0.15,
                               (2, 0): 0.26, (2, 1): 0.18, (2, 2): 0, (3, 0): 0.22, (3, 1): 0.15, (3, 2): 0.08,
                               (4, 0): 0.33, (4, 1): 0.23, (4, 2): 0.15, (5, 0): 0, (5, 1): 0, (5, 2): 0,
                               (7, 0): 0.14, (7, 1): 0.11, (7, 2): 0.08},
                           3: {(0, 0): 0.41, (0, 1): 0.58, (0, 2): 0.24, (1, 0): 0.25, (1, 1): 0.36, (1, 2): 0.15,
                               (2, 0): 0.18, (2, 1): 0.26, (2, 2): 0, (3, 0): 0.15, (3, 1): 0.22, (3, 2): 0.08,
                               (4, 0): 0.23, (4, 1): 0.33, (4, 2): 0.15, (5, 0): 0, (5, 1): 0, (5, 2): 0,
                               (7, 0): 0.11, (7, 1): 0.14, (7, 2): 0.08}}
        """(dict)
        {mission: {(sub_type, task): efficiency, (sub_type, task): efficiency ...}}
        """
        self.addition = {0: {((0, 0), (0, 0)): 0.69, ((0, 0), (0, 1)): 0.58, ((0, 0), (0, 2)): 0.45,
                             ((0, 1), (0, 1)): 0.43, ((0, 1), (0, 2)): 0.40, ((0, 2), (0, 2)): 0.34,
                             ((0, 0), (1, 0)): 0.41, ((0, 0), (1, 1)): 0.37, ((0, 0), (1, 2)): 0.35,
                             ((0, 1), (1, 1)): 0.22, ((0, 1), (1, 2)): 0.19, ((0, 2), (1, 2)): 0.16,
                             ((0, 0), (2, 0)): 0.45, ((0, 0), (2, 1)): 0.42,
                             ((0, 1), (2, 1)): 0.23,
                             ((0, 0), (3, 0)): 0.38, ((0, 0), (3, 1)): 0.35, ((0, 0), (3, 2)): 0.30,
                             ((0, 1), (3, 1)): 0.26, ((0, 1), (3, 2)): 0.18, ((0, 2), (3, 2)): 0.16,
                             ((0, 0), (4, 0)): 0.39, ((0, 0), (4, 1)): 0.35, ((0, 0), (4, 2)): 0.31,
                             ((0, 1), (4, 1)): 0.26, ((0, 1), (4, 2)): 0.18, ((0, 2), (4, 2)): 0.15,
                             ((0, 0), (5, 0)): 0.55, ((0, 0), (5, 1)): 0.46, ((0, 0), (5, 2)): 0.43,
                             ((0, 1), (5, 1)): 0.36, ((0, 1), (5, 2)): 0.28, ((0, 2), (5, 2)): 0.22,
                             ((0, 0), (7, 0)): 0.68, ((0, 0), (7, 1)): 0.61, ((0, 0), (7, 2)): 0.55,
                             ((0, 1), (7, 1)): 0.52, ((0, 1), (7, 2)): 0.34, ((0, 2), (7, 2)): 0.27,
                             ((1, 0), (0, 0)): 0.45, ((1, 0), (0, 1)): 0.41, ((1, 0), (0, 2)): 0.37,
                             ((1, 1), (0, 1)): 0.33, ((1, 1), (0, 2)): 0.29, ((1, 2), (0, 2)): 0.26,
                             ((1, 0), (1, 0)): 0.62, ((1, 0), (1, 1)): 0.57, ((1, 0), (1, 2)): 0.54,
                             ((1, 1), (1, 1)): 0.45, ((1, 1), (1, 2)): 0.38, ((1, 2), (1, 2)): 0.30,
                             ((1, 0), (2, 0)): 0.30, ((1, 0), (2, 1)): 0.64,
                             ((1, 1), (2, 1)): 0.52,
                             ((1, 0), (3, 0)): 0.75, ((1, 0), (3, 1)): 0.68, ((1, 0), (3, 2)): 0.60,
                             ((1, 1), (3, 1)): 0.49, ((1, 1), (3, 2)): 0.35, ((1, 2), (3, 2)): 0.30,
                             ((1, 0), (4, 0)): 0.42, ((1, 0), (4, 1)): 0.38, ((1, 0), (4, 2)): 0.37,
                             ((1, 1), (4, 1)): 0.33, ((1, 1), (4, 2)): 0.28, ((1, 2), (4, 2)): 0.20,
                             ((1, 0), (5, 0)): 0.35, ((1, 0), (5, 1)): 0.32, ((1, 0), (5, 2)): 0.28,
                             ((1, 1), (5, 1)): 0.23, ((1, 1), (5, 2)): 0.18, ((1, 2), (5, 2)): 0.14,
                             ((1, 0), (7, 0)): 0.80, ((1, 0), (7, 1)): 0.61, ((1, 0), (7, 2)): 0.55,
                             ((1, 1), (7, 1)): 0.39, ((1, 1), (7, 2)): 0.34, ((1, 2), (7, 2)): 0.30,
                             ((2, 0), (0, 0)): 0.22, ((2, 0), (0, 1)): 0.19, ((2, 0), (0, 2)): 0.16,
                             ((2, 1), (0, 1)): 0.14, ((2, 1), (0, 2)): 0.11,
                             ((2, 0), (1, 0)): 0.70, ((2, 0), (1, 1)): 0.63, ((2, 0), (1, 2)): 0.55,
                             ((2, 1), (1, 1)): 0.43, ((2, 1), (1, 2)): 0.38,
                             ((2, 0), (2, 0)): 0.90, ((2, 0), (2, 1)): 0.79,
                             ((2, 1), (2, 1)): 0.50,
                             ((2, 0), (3, 0)): 0.75, ((2, 0), (3, 1)): 0.64, ((2, 0), (3, 2)): 0.50,
                             ((2, 1), (3, 1)): 0.45, ((2, 1), (3, 2)): 0.40,
                             ((2, 0), (4, 0)): 0.55, ((2, 0), (4, 1)): 0.46, ((2, 0), (4, 2)): 0.43,
                             ((2, 1), (4, 1)): 0.36, ((2, 1), (4, 2)): 0.28,
                             ((2, 0), (5, 0)): 0.42, ((2, 0), (5, 1)): 0.38, ((2, 0), (5, 2)): 0.33,
                             ((2, 1), (5, 1)): 0.27, ((2, 1), (5, 2)): 0.21,
                             ((2, 0), (7, 0)): 0.71, ((2, 0), (7, 1)): 0.65, ((2, 0), (7, 2)): 0.58,
                             ((2, 1), (7, 1)): 0.49, ((2, 1), (7, 2)): 0.41,
                             ((3, 0), (0, 0)): 0.23, ((3, 0), (0, 1)): 0.20, ((3, 0), (0, 2)): 0.17,
                             ((3, 1), (0, 1)): 0.15, ((3, 1), (0, 2)): 0.13, ((3, 2), (0, 2)): 0.09,
                             ((3, 0), (1, 0)): 0.32, ((3, 0), (1, 1)): 0.27, ((3, 0), (1, 2)): 0.24,
                             ((3, 1), (1, 1)): 0.21, ((3, 1), (1, 2)): 0.18, ((3, 2), (1, 2)): 0.13,
                             ((3, 0), (2, 0)): 0.55, ((3, 0), (2, 1)): 0.47,
                             ((3, 1), (2, 1)): 0.37,
                             ((3, 0), (3, 0)): 0.29, ((3, 0), (3, 1)): 0.25, ((3, 0), (3, 2)): 0.22,
                             ((3, 1), (3, 1)): 0.19, ((3, 1), (3, 2)): 0.16, ((3, 2), (3, 2)): 0.12,
                             ((3, 0), (4, 0)): 0.39, ((3, 0), (4, 1)): 0.33, ((3, 0), (4, 2)): 0.30,
                             ((3, 1), (4, 1)): 0.26, ((3, 1), (4, 2)): 0.21, ((3, 2), (4, 2)): 0.15,
                             ((3, 0), (5, 0)): 0.44, ((3, 0), (5, 1)): 0.41, ((3, 0), (5, 2)): 0.34,
                             ((3, 1), (5, 1)): 0.29, ((3, 1), (5, 2)): 0.22, ((3, 2), (5, 2)): 0.18,
                             ((3, 0), (7, 0)): 0.81, ((3, 0), (7, 1)): 0.65, ((3, 0), (7, 2)): 0.56,
                             ((3, 1), (7, 1)): 0.41, ((3, 1), (7, 2)): 0.36, ((3, 2), (7, 2)): 0.33,
                             ((4, 0), (0, 0)): 0.48, ((4, 0), (0, 1)): 0.43, ((4, 0), (0, 2)): 0.38,
                             ((4, 1), (0, 1)): 0.31, ((4, 1), (0, 2)): 0.26, ((4, 2), (0, 2)): 0.21,
                             ((4, 0), (1, 0)): 0.45, ((4, 0), (1, 1)): 0.38, ((4, 0), (1, 2)): 0.35,
                             ((4, 1), (1, 1)): 0.30, ((4, 1), (1, 2)): 0.25, ((4, 2), (1, 2)): 0.16,
                             ((4, 0), (2, 0)): 0.43, ((4, 0), (2, 1)): 0.38,
                             ((4, 1), (2, 1)): 0.28,
                             ((4, 0), (3, 0)): 0.38, ((4, 0), (3, 1)): 0.33, ((4, 0), (3, 2)): 0.30,
                             ((4, 1), (3, 1)): 0.25, ((4, 1), (3, 2)): 0.19, ((4, 2), (3, 2)): 0.14,
                             ((4, 0), (4, 0)): 0.45, ((4, 0), (4, 1)): 0.41, ((4, 0), (4, 2)): 0.36,
                             ((4, 1), (4, 1)): 0.30, ((4, 1), (4, 2)): 0.22, ((4, 2), (4, 2)): 0.19,
                             ((4, 0), (5, 0)): 0.33, ((4, 0), (5, 1)): 0.29, ((4, 0), (5, 2)): 0.25,
                             ((4, 1), (5, 1)): 0.20, ((4, 1), (5, 2)): 0.17, ((4, 2), (5, 2)): 0.13,
                             ((4, 0), (7, 0)): 0.68, ((4, 0), (7, 1)): 0.62, ((4, 0), (7, 2)): 0.54,
                             ((4, 1), (7, 1)): 0.45, ((4, 1), (7, 2)): 0.34, ((4, 2), (7, 2)): 0.29,
                             ((5, 0), (1, 0)): 0.55, ((5, 0), (1, 1)): 0.46, ((5, 0), (1, 2)): 0.43,
                             ((5, 1), (1, 1)): 0.35, ((5, 1), (1, 2)): 0.32, ((5, 2), (1, 2)): 0.28,
                             ((5, 0), (3, 0)): 0.45, ((5, 0), (3, 1)): 0.42, ((5, 0), (3, 2)): 0.35,
                             ((5, 1), (3, 1)): 0.30, ((5, 1), (3, 2)): 0.23, ((5, 2), (3, 2)): 0.19,
                             ((5, 0), (4, 0)): 0.33, ((5, 0), (4, 1)): 0.27, ((5, 0), (4, 2)): 0.23,
                             ((5, 1), (4, 1)): 0.19, ((5, 1), (4, 2)): 0.14, ((5, 2), (4, 2)): 0.12
                             },
                         1: {((0, 0), (0, 0)): 0.43, ((0, 0), (0, 1)): 0.58, ((0, 0), (0, 2)): 0.34,
                             ((0, 1), (0, 1)): 0.69, ((0, 1), (0, 2)): 0.45, ((0, 2), (0, 2)): 0.34,
                             ((0, 0), (1, 0)): 0.22, ((0, 0), (1, 1)): 0.33, ((0, 0), (1, 2)): 0.19,
                             ((0, 1), (1, 1)): 0.41, ((0, 1), (1, 2)): 0.35, ((0, 2), (1, 2)): 0.16,
                             ((0, 0), (2, 0)): 0.29, ((0, 0), (2, 1)): 0.34,
                             ((0, 1), (2, 1)): 0.43,
                             ((0, 0), (3, 0)): 0.26, ((0, 0), (3, 1)): 0.20, ((0, 0), (3, 2)): 0.18,
                             ((0, 1), (3, 1)): 0.23, ((0, 1), (3, 2)): 0.30, ((0, 2), (3, 2)): 0.16,
                             ((0, 0), (4, 0)): 0.26, ((0, 0), (4, 1)): 0.43, ((0, 0), (4, 2)): 0.18,
                             ((0, 1), (4, 1)): 0.48, ((0, 1), (4, 2)): 0.31, ((0, 2), (4, 2)): 0.15,
                             ((0, 0), (5, 0)): 0.37, ((0, 0), (5, 1)): 0.44, ((0, 0), (5, 2)): 0.21,
                             ((0, 1), (5, 1)): 0.53, ((0, 1), (5, 2)): 0.40, ((0, 2), (5, 2)): 0.21,
                             ((0, 0), (7, 0)): 0.52, ((0, 0), (7, 1)): 0, ((0, 0), (7, 2)): 0.34,
                             ((0, 1), (7, 1)): 0.58, ((0, 1), (7, 2)): 0.55, ((0, 2), (7, 2)): 0.27,
                             ((1, 0), (0, 0)): 0.33, ((1, 0), (0, 1)): 0.33, ((1, 0), (0, 2)): 0.29,
                             ((1, 1), (0, 1)): 0.45, ((1, 1), (0, 2)): 0.37, ((1, 2), (0, 2)): 0.26,
                             ((1, 0), (1, 0)): 0.45, ((1, 0), (1, 1)): 0.57, ((1, 0), (1, 2)): 0.38,
                             ((1, 1), (1, 1)): 0.62, ((1, 1), (1, 2)): 0.54, ((1, 2), (1, 2)): 0.30,
                             ((1, 0), (2, 0)): 0.30, ((1, 0), (2, 1)): 0.63,
                             ((1, 1), (2, 1)): 0.70,
                             ((1, 0), (3, 0)): 0.49, ((1, 0), (3, 1)): 0.27, ((1, 0), (3, 2)): 0.35,
                             ((1, 1), (3, 1)): 0.75, ((1, 1), (3, 2)): 0.60, ((1, 2), (3, 2)): 0.30,
                             ((1, 0), (4, 0)): 0.33, ((1, 0), (4, 1)): 0.36, ((1, 0), (4, 2)): 0.28,
                             ((1, 1), (4, 1)): 0.42, ((1, 1), (4, 2)): 0.43, ((1, 2), (4, 2)): 0.20,
                             ((1, 0), (5, 0)): 0.23, ((1, 0), (5, 1)): 0.32, ((1, 0), (5, 2)): 0.18,
                             ((1, 1), (5, 1)): 0.35, ((1, 1), (5, 2)): 0.28, ((1, 2), (5, 2)): 0.14,
                             ((1, 0), (7, 0)): 0.39, ((1, 0), (7, 1)): 0, ((1, 0), (7, 2)): 0.34,
                             ((1, 1), (7, 1)): 0.80, ((1, 1), (7, 2)): 0.45, ((1, 2), (7, 2)): 0.30,
                             ((2, 0), (0, 0)): 0.34, ((2, 0), (0, 1)): 0.40, ((2, 0), (0, 2)): 0.30,
                             ((2, 1), (0, 1)): 0.50, ((2, 1), (0, 2)): 0.41,
                             ((2, 0), (1, 0)): 0.43, ((2, 0), (1, 1)): 0.64, ((2, 0), (1, 2)): 0.38,
                             ((2, 1), (1, 1)): 0.70, ((2, 1), (1, 2)): 0.55,
                             ((2, 0), (2, 0)): 0.50, ((2, 0), (2, 1)): 0.79,
                             ((2, 1), (2, 1)): 0.90,
                             ((2, 0), (3, 0)): 0.45, ((2, 0), (3, 1)): 0.46, ((2, 0), (3, 2)): 0.40,
                             ((2, 1), (3, 1)): 0.75, ((2, 1), (3, 2)): 0.50,
                             ((2, 0), (4, 0)): 0.36, ((2, 0), (4, 1)): 0.38, ((2, 0), (4, 2)): 0.28,
                             ((2, 1), (4, 1)): 0.55, ((2, 1), (4, 2)): 0.43,
                             ((2, 0), (5, 0)): 0.27, ((2, 0), (5, 1)): 0, ((2, 0), (5, 2)): 0.21,
                             ((2, 1), (5, 1)): 0.42, ((2, 1), (5, 2)): 0.33,
                             ((2, 0), (7, 0)): 0.49, ((2, 0), (7, 1)): 0, ((2, 0), (7, 2)): 0.41,
                             ((2, 1), (7, 1)): 0.71, ((2, 1), (7, 2)): 0.58,
                             ((3, 0), (0, 0)): 0.15, ((3, 0), (0, 1)): 0.35, ((3, 0), (0, 2)): 0.13,
                             ((3, 1), (0, 1)): 0.23, ((3, 1), (0, 2)): 0.17, ((3, 2), (0, 2)): 0.09,
                             ((3, 0), (1, 0)): 0.21, ((3, 0), (1, 1)): 0.68, ((3, 0), (1, 2)): 0.18,
                             ((3, 1), (1, 1)): 0.32, ((3, 1), (1, 2)): 0.24, ((3, 2), (1, 2)): 0.13,
                             ((3, 0), (2, 0)): 0.36, ((3, 0), (2, 1)): 0.64,
                             ((3, 1), (2, 1)): 0.55,
                             ((3, 0), (3, 0)): 0.19, ((3, 0), (3, 1)): 0.25, ((3, 0), (3, 2)): 0.16,
                             ((3, 1), (3, 1)): 0.29, ((3, 1), (3, 2)): 0.22, ((3, 2), (3, 2)): 0.12,
                             ((3, 0), (4, 0)): 0.26, ((3, 0), (4, 1)): 0.33, ((3, 0), (4, 2)): 0.21,
                             ((3, 1), (4, 1)): 0.39, ((3, 1), (4, 2)): 0.30, ((3, 2), (4, 2)): 0.15,
                             ((3, 0), (5, 0)): 0.19, ((3, 0), (5, 1)): 0.48, ((3, 0), (5, 2)): 0.14,
                             ((3, 1), (5, 1)): 0.33, ((3, 1), (5, 2)): 0.23, ((3, 2), (5, 2)): 0.11,
                             ((3, 0), (7, 0)): 0.41, ((3, 0), (7, 1)): 0, ((3, 0), (7, 2)): 0.36,
                             ((3, 1), (7, 1)): 0.81, ((3, 1), (7, 2)): 0.56, ((3, 2), (7, 2)): 0.33,
                             ((4, 0), (0, 0)): 0.31, ((4, 0), (0, 1)): 0.35, ((4, 0), (0, 2)): 0.26,
                             ((4, 1), (0, 1)): 0.48, ((4, 1), (0, 2)): 0.38, ((4, 2), (0, 2)): 0.21,
                             ((4, 0), (1, 0)): 0.30, ((4, 0), (1, 1)): 0.38, ((4, 0), (1, 2)): 0.24,
                             ((4, 1), (1, 1)): 0.43, ((4, 1), (1, 2)): 0.32, ((4, 2), (1, 2)): 0.18,
                             ((4, 0), (2, 0)): 0.28, ((4, 0), (2, 1)): 0.46,
                             ((4, 1), (2, 1)): 0.43,
                             ((4, 0), (3, 0)): 0.25, ((4, 0), (3, 1)): 0.33, ((4, 0), (3, 2)): 0.19,
                             ((4, 1), (3, 1)): 0.38, ((4, 1), (3, 2)): 0.30, ((4, 2), (3, 2)): 0.14,
                             ((4, 0), (4, 0)): 0.30, ((4, 0), (4, 1)): 0.41, ((4, 0), (4, 2)): 0.22,
                             ((4, 1), (4, 1)): 0.45, ((4, 1), (4, 2)): 0.36, ((4, 2), (4, 2)): 0.19,
                             ((4, 0), (5, 0)): 0.20, ((4, 0), (5, 1)): 0.27, ((4, 0), (5, 2)): 0.17,
                             ((4, 1), (5, 1)): 0.33, ((4, 1), (5, 2)): 0.25, ((4, 2), (5, 2)): 0.13,
                             ((4, 0), (7, 0)): 0.45, ((4, 0), (7, 1)): 0, ((4, 0), (7, 2)): 0.34,
                             ((4, 1), (7, 1)): 0.68, ((4, 1), (7, 2)): 0.54, ((4, 2), (7, 2)): 0.29,
                             ((5, 0), (0, 0)): 0.37, ((5, 0), (0, 1)): 0.44, ((5, 0), (0, 2)): 0.31,
                             ((5, 1), (0, 1)): 0.53, ((5, 1), (0, 2)): 0.40, ((5, 2), (0, 2)): 0.21,
                             ((5, 0), (1, 0)): 0.37, ((5, 0), (1, 1)): 0.32, ((5, 0), (1, 2)): 0.18,
                             ((5, 1), (1, 1)): 0.35, ((5, 1), (1, 2)): 0.28, ((5, 2), (1, 2)): 0.15,
                             ((5, 0), (3, 0)): 0.30, ((5, 0), (3, 1)): 0.26, ((5, 0), (3, 2)): 0.23,
                             ((5, 1), (3, 1)): 0.45, ((5, 1), (3, 2)): 0.35, ((5, 2), (3, 2)): 0.19,
                             ((5, 0), (4, 0)): 0.19, ((5, 0), (4, 1)): 0.29, ((5, 0), (4, 2)): 0.14,
                             ((5, 1), (4, 1)): 0.33, ((5, 1), (4, 2)): 0.23, ((5, 2), (4, 2)): 0.12
                             },
                         2: {((0, 0), (0, 0)): 0.72, ((0, 0), (0, 1)): 0.61, ((0, 0), (0, 2)): 0.55,
                             ((0, 1), (0, 1)): 0.51, ((0, 1), (0, 2)): 0.40, ((0, 2), (0, 2)): 0.28,
                             ((0, 0), (1, 0)): 0.49, ((0, 0), (1, 1)): 0.42, ((0, 0), (1, 2)): 0.37,
                             ((0, 1), (1, 1)): 0.33, ((0, 1), (1, 2)): 0.27, ((0, 2), (1, 2)): 0.19,
                             ((0, 0), (2, 0)): 0.52, ((0, 0), (2, 1)): 0.45,
                             ((0, 1), (2, 1)): 0.25,
                             ((0, 0), (3, 0)): 0.44, ((0, 0), (3, 1)): 0.37, ((0, 0), (3, 2)): 0.34,
                             ((0, 1), (3, 1)): 0.29, ((0, 1), (3, 2)): 0.34, ((0, 2), (3, 2)): 0.17,
                             ((0, 0), (4, 0)): 0.45, ((0, 0), (4, 1)): 0.38, ((0, 0), (4, 2)): 0.34,
                             ((0, 1), (4, 1)): 0.30, ((0, 1), (4, 2)): 0.25, ((0, 2), (4, 2)): 0.17,
                             ((0, 0), (7, 0)): 0.76, ((0, 0), (7, 1)): 0.65, ((0, 0), (7, 2)): 0.58,
                             ((0, 1), (7, 1)): 0.51, ((0, 1), (7, 2)): 0.42, ((0, 2), (7, 2)): 0.31,
                             ((1, 0), (0, 0)): 0.52, ((1, 0), (0, 1)): 0.44, ((1, 0), (0, 2)): 0.40,
                             ((1, 1), (0, 1)): 0.35, ((1, 1), (0, 2)): 0.38, ((1, 2), (0, 2)): 0.21,
                             ((1, 0), (1, 0)): 0.71, ((1, 0), (1, 1)): 0.60, ((1, 0), (1, 2)): 0.55,
                             ((1, 1), (1, 1)): 0.58, ((1, 1), (1, 2)): 0.39, ((1, 2), (1, 2)): 0.28,
                             ((1, 0), (2, 0)): 0.30, ((1, 0), (2, 1)): 0.64,
                             ((1, 1), (2, 1)): 0.50,
                             ((1, 0), (3, 0)): 0.86, ((1, 0), (3, 1)): 0.73, ((1, 0), (3, 2)): 0.66,
                             ((1, 1), (3, 1)): 0.58, ((1, 1), (3, 2)): 0.47, ((1, 2), (3, 2)): 0.34,
                             ((1, 0), (4, 0)): 0.47, ((1, 0), (4, 1)): 0.40, ((1, 0), (4, 2)): 0.36,
                             ((1, 1), (4, 1)): 0.31, ((1, 1), (4, 2)): 0.26, ((1, 2), (4, 2)): 0.34,
                             ((1, 0), (5, 0)): 0.39, ((1, 0), (5, 1)): 0.33, ((1, 0), (5, 2)): 0.30,
                             ((1, 1), (5, 1)): 0.26, ((1, 1), (5, 2)): 0.21, ((1, 2), (5, 2)): 0.16,
                             ((1, 0), (7, 0)): 0.92, ((1, 0), (7, 1)): 0.92, ((1, 0), (7, 2)): 0.83,
                             ((1, 1), (7, 1)): 0.72, ((1, 1), (7, 2)): 0.59, ((1, 2), (7, 2)): 0.43,
                             ((2, 0), (0, 0)): 0.25, ((2, 0), (0, 1)): 0.21, ((2, 0), (0, 2)): 0.19,
                             ((2, 1), (0, 1)): 0.16, ((2, 1), (0, 2)): 0.14,
                             ((2, 0), (1, 0)): 0.75, ((2, 0), (1, 1)): 0.64, ((2, 0), (1, 2)): 0.58,
                             ((2, 1), (1, 1)): 0.50, ((2, 1), (1, 2)): 0.41,
                             ((2, 0), (2, 0)): 0.96, ((2, 0), (2, 1)): 0.80,
                             ((2, 1), (2, 1)): 0.53,
                             ((2, 0), (3, 0)): 0.80, ((2, 0), (3, 1)): 0.68, ((2, 0), (3, 2)): 0.54,
                             ((2, 1), (3, 1)): 0.44, ((2, 1), (3, 2)): 0.32,
                             ((2, 0), (4, 0)): 0.57, ((2, 0), (4, 1)): 0.48, ((2, 0), (4, 2)): 0.44,
                             ((2, 1), (4, 1)): 0.38, ((2, 1), (4, 2)): 0.41,
                             ((2, 0), (5, 0)): 0.49, ((2, 0), (5, 1)): 0.42, ((2, 0), (5, 2)): 0.38,
                             ((2, 1), (5, 1)): 0.33, ((2, 1), (5, 2)): 0.27,
                             ((2, 0), (7, 0)): 0.82, ((2, 0), (7, 1)): 0.69, ((2, 0), (7, 2)): 0.63,
                             ((2, 1), (7, 1)): 0.55, ((2, 1), (7, 2)): 0.45,
                             ((3, 0), (0, 0)): 0.23, ((3, 0), (0, 1)): 0.20, ((3, 0), (0, 2)): 0.17,
                             ((3, 1), (0, 1)): 0.15, ((3, 1), (0, 2)): 0.13, ((3, 2), (0, 2)): 0.09,
                             ((3, 0), (1, 0)): 0.32, ((3, 0), (1, 1)): 0.27, ((3, 0), (1, 2)): 0.24,
                             ((3, 1), (1, 1)): 0.21, ((3, 1), (1, 2)): 0.18, ((3, 2), (1, 2)): 0.13,
                             ((3, 0), (2, 0)): 0.58, ((3, 0), (2, 1)): 0.49,
                             ((3, 1), (2, 1)): 0.39,
                             ((3, 0), (3, 0)): 0.29, ((3, 0), (3, 1)): 0.25, ((3, 0), (3, 2)): 0.22,
                             ((3, 1), (3, 1)): 0.19, ((3, 1), (3, 2)): 0.16, ((3, 2), (3, 2)): 0.12,
                             ((3, 0), (4, 0)): 0.39, ((3, 0), (4, 1)): 0.33, ((3, 0), (4, 2)): 0.30,
                             ((3, 1), (4, 1)): 0.26, ((3, 1), (4, 2)): 0.21, ((3, 2), (4, 2)): 0.15,
                             ((3, 0), (7, 0)): 0.94, ((3, 0), (7, 1)): 0.79, ((3, 0), (7, 2)): 0.63,
                             ((3, 1), (7, 1)): 0.52, ((3, 1), (7, 2)): 0.37, ((3, 2), (7, 2)): 0.56,
                             ((4, 0), (0, 0)): 0.56, ((4, 0), (0, 1)): 0.48, ((4, 0), (0, 2)): 0.43,
                             ((4, 1), (0, 1)): 0.38, ((4, 1), (0, 2)): 0.31, ((4, 2), (0, 2)): 0.22,
                             ((4, 0), (1, 0)): 0.45, ((4, 0), (1, 1)): 0.38, ((4, 0), (1, 2)): 0.35,
                             ((4, 1), (1, 1)): 0.30, ((4, 1), (1, 2)): 0.25, ((4, 2), (1, 2)): 0.18,
                             ((4, 0), (2, 0)): 0.48, ((4, 0), (2, 1)): 0.41,
                             ((4, 1), (2, 1)): 0.32,
                             ((4, 0), (3, 0)): 0.41, ((4, 0), (3, 1)): 0.35, ((4, 0), (3, 2)): 0.31,
                             ((4, 1), (3, 1)): 0.27, ((4, 1), (3, 2)): 0.23, ((4, 2), (3, 2)): 0.16,
                             ((4, 0), (4, 0)): 0.51, ((4, 0), (4, 1)): 0.43, ((4, 0), (4, 2)): 0.39,
                             ((4, 1), (4, 1)): 0.34, ((4, 1), (4, 2)): 0.28, ((4, 2), (4, 2)): 0.20,
                             ((4, 0), (5, 0)): 0.35, ((4, 0), (5, 1)): 0.30, ((4, 0), (5, 2)): 0.27,
                             ((4, 1), (5, 1)): 0.23, ((4, 1), (5, 2)): 0.19, ((4, 2), (5, 2)): 0.14,
                             ((4, 0), (7, 0)): 0.77, ((4, 0), (7, 1)): 0.65, ((4, 0), (7, 2)): 0.59,
                             ((4, 1), (7, 1)): 0.51, ((4, 1), (7, 2)): 0.42, ((4, 2), (7, 2)): 0.31,
                             ((5, 0), (1, 0)): 0.39, ((5, 0), (1, 1)): 0.33, ((5, 0), (1, 2)): 0.30,
                             ((5, 1), (1, 1)): 0.26, ((5, 1), (1, 2)): 0.21, ((5, 2), (1, 2)): 0.16,
                             ((5, 0), (2, 0)): 0.49, ((5, 0), (2, 1)): 0.42,
                             ((5, 1), (2, 1)): 0.33,
                             ((5, 0), (4, 0)): 0.35, ((5, 0), (4, 1)): 0.33, ((5, 0), (4, 2)): 0.27,
                             ((5, 1), (4, 1)): 0.23, ((5, 1), (4, 2)): 0.19, ((5, 2), (4, 2)): 0.14
                             },
                         3: {((0, 0), (0, 0)): 0.51, ((0, 0), (0, 1)): 0.61, ((0, 0), (0, 2)): 0.40,
                             ((0, 1), (0, 1)): 0.72, ((0, 1), (0, 2)): 0.55, ((0, 2), (0, 2)): 0.28,
                             ((0, 0), (1, 0)): 0.40, ((0, 0), (1, 1)): 0.44, ((0, 0), (1, 2)): 0.27,
                             ((0, 1), (1, 1)): 0.49, ((0, 1), (1, 2)): 0.37, ((0, 2), (1, 2)): 0.19,
                             ((0, 0), (2, 0)): 0.40, ((0, 0), (2, 1)): 0.59,
                             ((0, 1), (2, 1)): 0.61,
                             ((0, 0), (3, 0)): 0.29, ((0, 0), (3, 1)): 0.20, ((0, 0), (3, 2)): 0.24,
                             ((0, 1), (3, 1)): 0.86, ((0, 1), (3, 2)): 0.34, ((0, 2), (3, 2)): 0.17,
                             ((0, 0), (4, 0)): 0.31, ((0, 0), (4, 1)): 0.48, ((0, 0), (4, 2)): 0.25,
                             ((0, 1), (4, 1)): 0.45, ((0, 1), (4, 2)): 0.34, ((0, 2), (4, 2)): 0.17,
                             ((0, 0), (5, 0)): 0.38, ((0, 0), (5, 1)): 0.49, ((0, 0), (5, 2)): 0.45,
                             ((0, 1), (5, 1)): 0.39, ((0, 1), (5, 2)): 0.45, ((0, 2), (5, 2)): 0.24,
                             ((0, 0), (7, 0)): 0.43, ((0, 0), (7, 1)): 0, ((0, 0), (7, 2)): 0.35,
                             ((0, 1), (7, 1)): 0.70, ((0, 1), (7, 2)): 0.53, ((0, 2), (7, 2)): 0.30,
                             ((1, 0), (0, 0)): 0.35, ((1, 0), (0, 1)): 0.42, ((1, 0), (0, 2)): 0.38,
                             ((1, 1), (0, 1)): 0.52, ((1, 1), (0, 2)): 0.40, ((1, 2), (0, 2)): 0,
                             ((1, 0), (1, 0)): 0.58, ((1, 0), (1, 1)): 0.60, ((1, 0), (1, 2)): 0.39,
                             ((1, 1), (1, 1)): 0.71, ((1, 1), (1, 2)): 0.55, ((1, 2), (1, 2)): 0.28,
                             ((1, 0), (2, 0)): 0.30, ((1, 0), (2, 1)): 0.64,
                             ((1, 1), (2, 1)): 0.75,
                             ((1, 0), (3, 0)): 0.58, ((1, 0), (3, 1)): 0.27, ((1, 0), (3, 2)): 0.47,
                             ((1, 1), (3, 1)): 0.86, ((1, 1), (3, 2)): 0.66, ((1, 2), (3, 2)): 0.34,
                             ((1, 0), (4, 0)): 0.31, ((1, 0), (4, 1)): 0.38, ((1, 0), (4, 2)): 0.26,
                             ((1, 1), (4, 1)): 0.47, ((1, 1), (4, 2)): 0.36, ((1, 2), (4, 2)): 0.18,
                             ((1, 0), (5, 0)): 0.26, ((1, 0), (5, 1)): 0.33, ((1, 0), (5, 2)): 0.21,
                             ((1, 1), (5, 1)): 0.39, ((1, 1), (5, 2)): 0.30, ((1, 2), (5, 2)): 0.16,
                             ((1, 0), (7, 0)): 0.41, ((1, 0), (7, 1)): 0, ((1, 0), (7, 2)): 0.37,
                             ((1, 1), (7, 1)): 0.92, ((1, 1), (7, 2)): 0.62, ((1, 2), (7, 2)): 0.43,
                             ((2, 0), (0, 0)): 0.49, ((2, 0), (0, 1)): 0.55, ((2, 0), (0, 2)): 0.38,
                             ((2, 1), (0, 1)): 0.70, ((2, 1), (0, 2)): 0.54,
                             ((2, 0), (1, 0)): 0.50, ((2, 0), (1, 1)): 0.64, ((2, 0), (1, 2)): 0.41,
                             ((2, 1), (1, 1)): 0.75, ((2, 1), (1, 2)): 0.58,
                             ((2, 0), (2, 0)): 0.55, ((2, 0), (2, 1)): 0.82,
                             ((2, 1), (2, 1)): 0.75,
                             ((2, 0), (3, 0)): 0.32, ((2, 0), (3, 1)): 0.49, ((2, 0), (3, 2)): 0.25,
                             ((2, 1), (3, 1)): 0.68, ((2, 1), (3, 2)): 0.44,
                             ((2, 0), (4, 0)): 0.44, ((2, 0), (4, 1)): 0.41, ((2, 0), (4, 2)): 0.32,
                             ((2, 1), (4, 1)): 0.80, ((2, 1), (4, 2)): 0.54,
                             ((2, 0), (5, 0)): 0.33, ((2, 0), (5, 1)): 0, ((2, 0), (5, 2)): 0.27,
                             ((2, 1), (5, 1)): 0.49, ((2, 1), (5, 2)): 0.38,
                             ((2, 0), (7, 0)): 0.55, ((2, 0), (7, 1)): 0, ((2, 0), (7, 2)): 0.45,
                             ((2, 1), (7, 1)): 0.82, ((2, 1), (7, 2)): 0.63,
                             ((3, 0), (0, 0)): 0.15, ((3, 0), (0, 1)): 0.37, ((3, 0), (0, 2)): 0.13,
                             ((3, 1), (0, 1)): 0.23, ((3, 1), (0, 2)): 0.17, ((3, 2), (0, 2)): 0.09,
                             ((3, 0), (1, 0)): 0.21, ((3, 0), (1, 1)): 0.73, ((3, 0), (1, 2)): 0.18,
                             ((3, 1), (1, 1)): 0.32, ((3, 1), (1, 2)): 0.24, ((3, 2), (1, 2)): 0.13,
                             ((3, 0), (2, 0)): 0.39, ((3, 0), (2, 1)): 0.54,
                             ((3, 1), (2, 1)): 0.58,
                             ((3, 0), (3, 0)): 0.19, ((3, 0), (3, 1)): 0.25, ((3, 0), (3, 2)): 0.16,
                             ((3, 1), (3, 1)): 0.29, ((3, 1), (3, 2)): 0.22, ((3, 2), (3, 2)): 0.12,
                             ((3, 0), (4, 0)): 0.26, ((3, 0), (4, 1)): 0.35, ((3, 0), (4, 2)): 0.21,
                             ((3, 1), (4, 1)): 0.39, ((3, 1), (4, 2)): 0.30, ((3, 2), (4, 2)): 0.15,
                             ((3, 0), (5, 0)): 0.19, ((3, 0), (5, 1)): 0.48, ((3, 0), (5, 2)): 0.14,
                             ((3, 1), (5, 1)): 0.33, ((3, 1), (5, 2)): 0.23, ((3, 2), (5, 2)): 0.11,
                             ((3, 0), (7, 0)): 0.52, ((3, 0), (7, 1)): 0, ((3, 0), (7, 2)): 0.45,
                             ((3, 1), (7, 1)): 0.94, ((3, 1), (7, 2)): 0.63, ((3, 2), (7, 2)): 0,
                             ((4, 0), (0, 0)): 0.38, ((4, 0), (0, 1)): 0.38, ((4, 0), (0, 2)): 0.31,
                             ((4, 1), (0, 1)): 0.56, ((4, 1), (0, 2)): 0.43, ((4, 2), (0, 2)): 0.22,
                             ((4, 0), (1, 0)): 0.30, ((4, 0), (1, 1)): 0.40, ((4, 0), (1, 2)): 0.25,
                             ((4, 1), (1, 1)): 0.45, ((4, 1), (1, 2)): 0.35, ((4, 2), (1, 2)): 0.18,
                             ((4, 0), (2, 0)): 0.32, ((4, 0), (2, 1)): 0.68,
                             ((4, 1), (2, 1)): 0.48,
                             ((4, 0), (3, 0)): 0.27, ((4, 0), (3, 1)): 0.33, ((4, 0), (3, 2)): 0.23,
                             ((4, 1), (3, 1)): 0.41, ((4, 1), (3, 2)): 0.31, ((4, 2), (3, 2)): 0.12,
                             ((4, 0), (4, 0)): 0.34, ((4, 0), (4, 1)): 0.43, ((4, 0), (4, 2)): 0.28,
                             ((4, 1), (4, 1)): 0.51, ((4, 1), (4, 2)): 0.39, ((4, 2), (4, 2)): 0.20,
                             ((4, 0), (5, 0)): 0.23, ((4, 0), (5, 1)): 0.33, ((4, 0), (5, 2)): 0.19,
                             ((4, 1), (5, 1)): 0.35, ((4, 1), (5, 2)): 0.27, ((4, 2), (5, 2)): 0.14,
                             ((4, 0), (7, 0)): 0.51, ((4, 0), (7, 1)): 0, ((4, 0), (7, 2)): 0.42,
                             ((4, 1), (7, 1)): 0.77, ((4, 1), (7, 2)): 0.59, ((4, 2), (7, 2)): 0.31,
                             ((5, 0), (0, 0)): 0.38, ((5, 0), (0, 1)): 0.49, ((5, 0), (0, 2)): 0.30,
                             ((5, 1), (0, 1)): 0.59, ((5, 1), (0, 2)): 0.45, ((5, 2), (0, 2)): 0.24,
                             ((5, 0), (1, 0)): 0.26, ((5, 0), (1, 1)): 0.33, ((5, 0), (1, 2)): 0.21,
                             ((5, 1), (1, 1)): 0.39, ((5, 1), (1, 2)): 0.30, ((5, 2), (1, 2)): 0.16,
                             ((5, 0), (3, 0)): 0.38, ((5, 0), (3, 1)): 0.27, ((5, 0), (3, 2)): 0.33,
                             ((5, 1), (3, 1)): 0.57, ((5, 1), (3, 2)): 0.42, ((5, 2), (3, 2)): 0.27,
                             ((5, 0), (4, 0)): 0.23, ((5, 0), (4, 1)): 0.30, ((5, 0), (4, 2)): 0.19,
                             ((5, 1), (4, 1)): 0.35, ((5, 1), (4, 2)): 0.27, ((5, 2), (4, 2)): 0.14
                             },
                         }
        '''
        """(dict)
        {mission:((sub_type, task), (sub_type, task)): addition, ((sub_type, task), (sub_type, task)): addition...}
        """

    def step(self, agent, mission):
        """
        形成联盟函数

        输出：list [
                        {'city':夺控点1,'mission':2,'member':[obj_id,betree],[obj_id,betree]},
                        {'city'：夺控点2,'mission':2,'member':[obj_id,betree],[obj_id,betree]},
                        {'city'：夺控点3,'mission':2,'member':[obj_id,betree],[obj_id,betree]}...
                    ]
        """
        operators = []
        for operator in agent.observation['operators'] + agent.observation['passengers']:
            if operator['color'] == agent.color:
                operators.append(operator)
        self.operators = operators
        city_sort_result = self.city_sort(agent)  # 夺控点排序
        begin1 = time.time()
        union_1st = self.initial_alliance(agent, city_sort_result)
        # finish1 = time.time()
        # time_union1 = finish1 - begin1
        # print('↓time_union1↓')
        # print(time_union1)
        if self.event_trigger(agent, union_1st, mission):  # 判断是否有事件触发 MISSION怎么填
            cities_rank_mission = self.rank_cities(agent, mission)  # 再次给夺控点排序
            self.rank_city_2 = cities_rank_mission  # {city:[概率,mission],city:[概率,mission]}
            begin2 = time.time()
            union_2nd = self.change_union_again(agent, union_1st, cities_rank_mission)  # 算子转移联盟 一个集合
            # finish2 = time.time()
            # time_union2 = finish2 - begin2
            # print('↓算子转移联盟↓')
            # print(time_union2)
            # begin3 = time.time()
            union_3nd = self.choose_max_union(agent, union_2nd)  # 选出每个夺控点 效能值最大的联盟
            # finish3 = time.time()
            # time_union3 = finish3 - begin3
            # print('↓选出每个夺控点效能值最大的联盟↓')
            # print(time_union3)
            # print('↓union_3nd↓')
            # print(union_3nd)
            # begin4 = time.time()
            union_4nd = self.choose_union_operator(agent, union_3nd)  # 得出联盟
            # finish4 = time.time()
            # time_union4 = finish4 - begin4
            # print('↓得出联盟↓')
            # print(time_union4)
            # print('union_4nd')
            # print(union_4nd)
            # time3 = agent.observation['time']['cur_step']
            # print(time3)
            if self.empty_union:
                print('kong')
                # if len(self.empty_union) > 1:
                #     mission_list  = []
                #     for i in self.empty_union:
                #         mission_list.append(i['mission'])
                #     if 1 in mission_list or 3 in mission_list:
                begin5 = time.time()
                union_5nd = self.empty_change(agent, union_4nd)  # 保证联盟基本兵力
                # finish5 = time.time()
                # time_union5 = finish5 - begin5
                # print('↓保证联盟基本兵力↓')
                # print(time_union5)
                # print('union_5nd')
                # print(union_5nd)
                # begin6 = time.time()
                union_6nd = self.betree_change(agent, union_5nd)  # 改变算子行为
                # finish6 = time.time()
                # time_union6 = finish6 - begin6
                # print('↓改变算子行为↓')
                # print(time_union6)
            else:
                begin6 = time.time()
                union_6nd = self.betree_change(agent, union_4nd)
                # finish6 = time.time()
                # time_union6 = finish6 - begin6
                # print('↓改变算子行为↓')
                # print(time_union6)
        else:
            begin6 = time.time()
            union_6nd = union_1st
            # finish6 = time.time()
            # time_union6 = finish6 - begin6
            # print('↓改变算子行为↓')
            # print(time_union6)

        members_id = []
        Infantry_id = []
        for union in union_6nd:
            for member in union['member']:
                members_id.append(member[0])
        for id in self.bubing:
            if id not in members_id:
                Infantry_id.append(id)
        if Infantry_id:
            for id in Infantry_id:
                standby_union = random.choice(union_6nd)
                if standby_union['mission'] == 0 or standby_union['mission'] == 2:
                    standby_union['member'].append([id, 0])
                else:
                    standby_union['member'].append([id, 1])
        # print('union_6nd')
        # print(union_6nd)
        return union_6nd

        # if self.bubing:
        #     bubing_copy = copy.deepcopy(self.bubing)
        #     add_bubing = []
        #     for i in union_6nd:
        #         member_list = []
        #         for member in i['member']:
        #             member_list.append(member[0])
        #         for i in self.bubing:
        #             if i not in member_list:
        #                 add_bubing.append(i)
        #             else:
        #                 bubing_copy.remove(i)
        #     if bubing_copy:
        #         for j in range(len(bubing_copy)):
        #             add_bubing[j]['member'].append(bubing_copy)
        #         union_6copy = copy.deepcopy(union_6nd)
        #         union_6final = []
        #         for i in union_6nd:
        #             for j in add_bubing:
        #                 if i['city'] == j['city']:
        #                     union_6copy.remove(i)
        #         for i in union_6copy:
        #             union_6final.append(i)
        #         for i in add_bubing:
        #             union_6final.append(i)
        #         return union_6final
        #     else:
        #         return union_6nd
        # else:

        # union_6nd.append({'overall_operator':self.overall_operator})
        # for i in union_6nd:
        #     for type, obj_list in self.overall_operator.items():
        #         for obj_id in obj_list:
        #             if 'member' in i.keys():
        #                 i['member'].append([obj_id])

    def city_sort(self, agent):
        """
        夺控点排序函数
        根据夺控点的距离、位置，按照性价比进行排序
        输出夺控点优先级结果{多控点坐标：概率,多控点坐标：概率}
        """

        d_list = []
        city_coord = []
        cur_hex = []
        value = []
        value_fa = {}
        i_hex = []
        i_value = []
        city_sort = {}  # {夺控点坐标：概率;夺控点坐标：概率}
        for cities in agent.observation['cities']:  # 遍历夺控点
            city_value = cities['value'] * 0.002  # 取出夺控点分值
            city_coord.append(cities['coord'])  # 存放夺控点坐标
            value.append(city_value)  # 存放夺控点分值
        self.cities = city_coord
        for operator in agent.observation['operators']:
            cur_hex.append(operator['cur_hex'])  # 取出我方算子坐标
        row_list = []
        col_list = []
        distance_list = []
        for i in cur_hex:
            row_city, col_city = divmod(i, 100)
            row_list.append(row_city)  # 行
            col_list.append(col_city)  # 列
        row_min = min(row_list)
        col_min = min(col_list)
        row_max = max(row_list)
        col_max = max(col_list)
        center = (row_min + int(0.5 * (row_max - row_min))) * 100 + \
                 (col_min + int(0.5 * (col_max - col_min)))  # 我方算子的中心点位
        for coord in city_coord:
            distance = agent.map.get_distance(center, coord)  #
            d_list.append(distance)
            d = round(5 / distance, 2)  # 保留两位小数
            distance_list.append(d)
        # final_value = list(map(lambda x, y: x+y, value, distance_list))  # 两个值加在一起 具体比例是多少待计算
        final_value = distance_list
        for i in range(len(city_coord)):
            a = city_coord[i]
            b = final_value[i]
            value_fa.update({(a, b)})  # 把数据结构变成元组的形式
            # value_fa.update((city_coord[i], final_value[i]))
        value_tuplelist = list(zip(value_fa.values(), value_fa.keys()))
        value_tuplelist_sort = sorted(value_tuplelist, reverse=True)  # 排序
        self.sort1_max_hex = value_tuplelist_sort[0][1]

        for i in value_tuplelist_sort:
            i_hex.append(i[1])
            i_value.append(i[0])

        self.sort_1.append([i_hex[0], i_hex[1]])
        self.sort_1.append([i_hex[2], i_hex[3], i_hex[4]])

        def weight_sampling(w_list):  # 归一化函数
            ran = np.random.uniform(0, 1)
            sum = 0
            for i in range(len(w_list)):
                sum += w_list[i]
                if (ran < sum):
                    return i

        num_list = []
        account_list = []
        for i in range(10000):
            num_list.append(weight_sampling(i_value))
        for i in range(len(i_value)):
            account_list.append(num_list.count(i))  # 进行计数 统计出现过的次数
        for i in range(len(i_hex)):
            city_sort.update({i_hex[i]: round(account_list[i] / sum(account_list), 3)})  # 保留三位小数
        return city_sort

    def initial_alliance(self, agent, city_sort):
        """
        初始联盟形成函数
        将算子平均分配到每个联盟中
        输出：list [
                  {'city':坐标,'mission':0,'member':[[obj_id,be_tree],[obj_id,be_tree]...]},...
                  {'city':坐标,'mission':0,'member':[[obj_id,be_tree],[obj_id,be_tree]...]},
                 ]
        """
        union = []
        cities = []
        num = []
        # city_sort = {3730: 0.241, 3427: 0.233, 3632: 0.185, 3529: 0.178, 4129: 0.163}
        for i in city_sort:
            union.append({'city': i, 'mission': 0})  # 联盟添加夺控点坐标 确定进攻方式
            n = city_sort[i]
            num.append(n)
            cities.append(i)  # 按照排序结果取出夺控点
        operator_standby = []  # 按类型存放算子

        # 按类型存放算子
        tank_list = []  # 坦克列表0
        zhanche_list = []  # 战车列表1
        bubing_list = []  # 步兵列表2
        wuren_zhanche_list = []  # 无人战车4
        paobing_list = []  # 炮兵3
        UAV_list = []  # 无人机5
        helicopter_list = []  # 直升机6
        CruiseMissle_list = []  # 巡飞弹 7
        transport_heli_list = []  # 运输直升机 8
        air_defense_list = []  # 防空算子 type=2
        recon_vehicle = []  # 侦察型战车9
        radar_vehicle = []  # 炮兵校射雷达车10
        fort_inf = []  # 人员工事11
        fort_vehi = []  # 车辆工事12
        mine_layer_list = []  # 布雷车13
        clear_layer_list = []  # 扫雷车14
        air_gun_list = []  # 防控高炮15
        air_platoon_list = []  # 便携防空导弹排16
        air_craftVehi_list = []  # 车载防空导弹车17
        operators_n = agent.observation['operators'] + agent.observation['passengers']  # 算子集合
        for operator in operators_n:
            if operator['color'] == agent.color:
                operator_standby.append(operator)
        for single in operator_standby:  # 遍历算子
            if single['sub_type'] == 0:
                tank_list.append(single['obj_id'])  # 坦克列表0
            if single['sub_type'] == 1:
                zhanche_list.append(single['obj_id'])  # 战车列表1
            if single['sub_type'] == 2:
                bubing_list.append(single['obj_id'])  # 步兵列表2
            if single['sub_type'] == 3:
                paobing_list.append(single['obj_id'])  # 炮兵列表3
            if single['sub_type'] == 4:
                wuren_zhanche_list.append(single['obj_id'])  # 无人战车列表4
            if single['sub_type'] == 5:
                UAV_list.append(single['obj_id'])  # 无人机列表5
            if single['sub_type'] == 6:
                helicopter_list.append(single['obj_id'])  # 直升机列表6
            # if single['sub_type'] == 7:
            #     CruiseMissle_list.append(single['obj_id'])  # 巡飞弹列表7
            if single['sub_type'] == 8:
                transport_heli_list.append(single['obj_id'])  # 运输直升机列表8
            if single['type'] == 2:  # subtype5678
                air_defense_list.append(single['obj_id'])  # 防空算子列表5678
            if single['sub_type'] == 9:
                recon_vehicle.append(single['obj_id'])  # 侦察型战车9
            if single['sub_type'] == 10:
                radar_vehicle.append(single['obj_id'])  # 炮兵校射雷达车10
            # if single['sub_type'] == 11:
            #     fort_inf.append(single['obj_id'])  # 人员工事11
            # if single['sub_type'] == 12:
            #     fort_vehi.append(single['obj_id'])  # 车辆工事12
            # if single['sub_type'] == 13:
            #     mine_layer_list.append(single['obj_id'])  # 布雷车13
            if single['sub_type'] == 14:
                clear_layer_list.append(single['obj_id'])  # 扫雷车14
            # if single['sub_type'] == 15:
            #     air_gun_list.append(single['obj_id'])  # 防空高炮15
            # if single['sub_type'] == 16:
            #     air_platoon_list.append(single['obj_id'])  # 便携防空导弹排16
            # if single['sub_type'] == 17:
            #     air_craftVehi_list.append(single['obj_id'])  # 车载防空导弹车17
        self.paobing = paobing_list
        self.bubing = bubing_list
        self.cruise = CruiseMissle_list
        self.uav = UAV_list  # 无人机5
        self.tank = tank_list
        self.zc = zhanche_list

        """
        添加全局算子 无人机拆出来 
              运输直升机8（只针对步兵只服务步兵） 多配合步兵多的联盟 
              炮兵3 巡飞弹7  人员工事11 车辆工事12   扫雷车14 
              防空高炮15 / 便携防空导弹排16 / 车载防空导弹车17  炮兵校射雷达车10（ 只服务炮兵）
        """
        if paobing_list:
            self.overall_operator.update({'artillery': paobing_list})
        if UAV_list:
            self.overall_operator.update({'uav': UAV_list})
        # if CruiseMissle_list:
        #     self.overall_operator.update({'cruise': CruiseMissle_list})
        # if transport_heli_list:  # 运输直升机
        #     self.overall_operator.update({'transport_heli': transport_heli_list})
        # if fort_inf:  # 人员工事
        #     self.overall_operator.update({'people_stay': fort_inf})
        # if fort_vehi:  # 车辆工事
        #     self.overall_operator.update({'vehicle_stay': fort_vehi})
        # if clear_layer_list:  # 扫雷车
        #     self.overall_operator.update({'clear_layer': clear_layer_list})
        # if air_gun_list:  # 防空高炮
        #     self.overall_operator.update({'air_gun': air_gun_list})
        # if air_platoon_list:  # 便携防空导弹排16
        #     self.overall_operator.update({'air_platoon': air_platoon_list})
        # if air_craftVehi_list:  # 车载防空导弹车17
        #     self.overall_operator.update({'air_craftVehi': air_craftVehi_list})
        if radar_vehicle:  # 炮兵校射雷达车10（ 只服务炮兵）
            self.overall_operator.update({'radar_vehicle': radar_vehicle})

        def operator_add(num_list, list1):
            """
                每个算子分配一个夺控点 权重大的夺控点会分配到多个算子
                输入：每个夺控点的权重值 list
                输出：list [
                           [夺控点1,obj_id],[夺控点2,obj_id],...
                         ]
            """
            result0 = tuple(num_list)
            result = []
            city_standby = random.choices(cities, weights=result0, k=len(list1))
            for i in range(len(list1)):
                result.append([city_standby[i], list1[i]])
            return result

        tank_result = []
        # tank_append = []
        hex_list = []
        for i in city_sort:
            hex_list.append(i)
        if tank_list:  # 添加坦克
            if len(hex_list) > len(tank_list):
                for i in range(len(tank_list)):
                    tank_result.append([hex_list[i], tank_list[i]])
            else:
                tank_copy = copy.deepcopy(tank_list)
                for i in range(len(hex_list)):
                    tank_result.append([hex_list[i], tank_list[i]])
                    tank_copy.remove(tank_list[i])
                if tank_copy:
                    for i in range(len(tank_copy)):
                        tank_result.append([hex_list[i], tank_copy[i]])

            # tank_result = operator_add(num, tank_list)
        # if tank_result:
        #     for i in tank_result:
        #         hex_list.append(i[0])  # 存坐标
        #     for i in self.cities:
        #         if i not in hex_list:
        #             tank_append.append(i)
        # print(tank_append)
        zc_result = []
        if zhanche_list:  # 添加战车1
            zc_result = operator_add(num, zhanche_list)
        wrzc_result = []
        if wuren_zhanche_list:  # 添加无人战车4
            wrzc_result = operator_add(num, wuren_zhanche_list)
        bubing_result = []
        if bubing_list:  # 步兵 2
            bubing_result = operator_add(num, bubing_list)
        for i in range(len(transport_heli_list)):
            bubing_result[i].append(transport_heli_list[i])
        helicopter_result = []
        if helicopter_list:  # 直升机 6
            helicopter_result = operator_add(num, helicopter_list)
        recon_vehicle_result = []
        if radar_vehicle:  # 侦察型战车9
            recon_vehicle_result = operator_add(num, recon_vehicle)
        clear_layer_result = []
        if clear_layer_list:  # 扫雷车14
            clear_layer_result = operator_add(num, clear_layer_list)
            self.clear_mine_result = clear_layer_result  # 传给self 输出给扫雷车行为树
        uav_result = []
        if UAV_list:  # 根据夺控点位置分配2个无人机
            for i in range(len(UAV_list)):
                uav_result.append([random.choice(self.sort_1[i]), UAV_list[i]])

        def city_operator_union(operator_result, union):
            """
            集合夺控点的算子
            operator_result:(list)
            union:(list) [
                          {'city':,'mission':},
                          {'city':,'mission':},
                        ]
            """
            for i in operator_result:
                for j in union:
                    if i[0] == j['city']:  # 集合每个夺控点的算子
                        if 'member' in j.keys():
                            # if len(i) < 2:
                            j['member'].append([i[1]])
                            # else:
                            #     i_new = copy.deepcopy(i)
                            #     i_new.remove(i[0])
                            #     for new_single in i_new:
                            #         j['member'].append([new_single])
                        else:
                            j.update({'member': [[i[1]]]})
            for i in union:
                if 'member' not in i.keys():
                    i.update({'member': []})
                    # else:
                    #     j.update({'member': []})
            return union

        union_tank = city_operator_union(tank_result, union)
        union_zc = city_operator_union(zc_result, union_tank)
        member_len = []
        u_choose = None
        tank_choose = None
        zero_list = []
        # for i in union_zc:
        #     member_len.append(len(i['member']))
        #
        # if 0 in member_len:
        #     # for j in member_len:
        #     #     if j == 0:
        #     #         zero_list.append(j)
        #     # if len(zero_list) > 1:
        #     union_zc_add = copy.deepcopy(union_zc)
        #     for i in range(len(member_len)):
        #         if member_len[i] == 0:  # 没有攻击算子
        #             m_choose = member_len.index(max(member_len))
        #             member_choose = union_zc_add[m_choose]
        #             u_choose =copy.deepcopy(member_choose)
        #             if member_choose['member']:
        #                 tank = random.choice(member_choose['member'])
        #                 tank_choose = [tank[0]]
        #                 union_zc_add[i]['member'].append(tank_choose)
        #         if u_choose:
        #             for i in union_zc_add:
        #                 if i['city'] == u_choose['city']:
        #                     if tank_choose in i['member']:
        #                         i['member'].remove(tank_choose)
        #                         u_choose.clear()
        #                         break
        # else:
        #     union_zc_add = union_zc
        union_zc_add = union_zc
        union_wrzc = city_operator_union(wrzc_result, union_zc_add)
        union_copy = copy.deepcopy(union_wrzc)
        union_bubing = city_operator_union(bubing_result, union_copy)
        union_helicopter = city_operator_union(helicopter_result, union_bubing)
        union_recon_vehi = city_operator_union(recon_vehicle_result, union_helicopter)
        # union_uav = city_operator_union(uav_result, union_recon_vehi)
        union_clear_layer = city_operator_union(clear_layer_result, union_recon_vehi)
        union_final = union_clear_layer

        # for i in union_final:  # 在每一个联盟中添加独立联盟的算子  最后在添加
        #     if 'member' not in i.keys():  # 权重小的夺控点可能没有分配到算子
        #         i.update({'member': []})  # 添加key：'member'
        """"
        添加全局算子
                for i in union_final:  # 在每一个联盟中添加独立联盟的算子  最后在添加
            if 'member' not in i.keys():  # 权重小的夺控点可能没有分配到算子
                i.update({'member': []})  # 添加key：'member'
                for type, obj_list in self.overall_operator.items():
                    for obj_id in obj_list:
                        if 'member' in i.keys():
                            i['member'].append([obj_id])
            else:
                for type, obj_list in self.overall_operator.items():
                    for obj_id in obj_list:
                        if 'member' in i.keys():
                            i['member'].append([obj_id])

        """
        for i in union_final:  # 确定行为树  0进攻 1 2 3
            for member in i['member']:
                member.append(0)  # 初始状态下 所有算子行为树均为进攻

        return union_final

    def event_trigger(self, agent, union, big_mission):  # 事件触发
        last_enemies_cities = {}  # 记录夺控点周围敌方算子的情况（self）
        enemies_cities = {}  # 判断当前态势下夺控点周围的敌方算子
        for city in agent.observation['cities']:  # 事件1：我方占领夺控点
            if (city['flag'] == agent.color) and (city['coord'] not in self.our_cities):
                self.our_cities.append(city['coord'])
                return True
            else:
                continue
        if self.mission != big_mission:  # 事件2：大mission层发生改变
            self.mission = big_mission
            return True
        for single_union in union:  # 事件3：我方某个联盟内的成员快被消灭完
            if 'member' in single_union.keys():
                if len(single_union['member']) <= 3:
                    return True

        for city in agent.observation['cities']:  # 事件4：夺控点周围敌方算子变多
            i = 0
            for operator in agent.observation['operators'] + agent.observation['passengers']:
                if operator['color'] != agent.color:
                    if agent.map.get_distance(operator['cur_hex'], city['coord']) < 4:
                        i += 1
            enemies_cities.update({city['coord']: i})
        if last_enemies_cities:
            for city, counter in enemies_cities:
                if city in self.last_enemies_cities[city] and counter > self.last_enemies_cities[city]:
                    self.last_enemies_cities[city] = counter
                    return True
                else:
                    continue
        return False

        # TODO:事件5：我方情况

    def count_real_distance(self, agent, pos1, pos2):
        max_speed = 20
        pos_star = pos1
        move_time = 0
        current_speed = 0
        route = agent.map.gen_move_route(pos1, pos2, MoveType.Maneuver)
        move_cost = agent.map.cost[MoveType.Maneuver]
        for pos_end in route[0]:
            cost = move_cost[pos_star // 100][pos_star % 100][pos_end]
            current_speed = max_speed / cost
            pos_star = pos_end
            if current_speed:
                move_time += current_speed
        real_distance = move_time / max_speed
        return real_distance

    def rank_cities(self, agent, MIISON):
        blank_cities = {}  # 未被夺控的目标点
        enemy_cities = {}  # 敌方占领的夺控点
        our_cities = {}  # 我方占领的夺控点
        cities_scores = {}  # 夺控点分数
        cities_weight = {}  # 夺控点权重
        for city in agent.observation['cities']:  # 夺控点的分值和距离
            if city['flag'] != agent.color and city['flag'] != -1:
                enemy_cities.update(
                    {city['coord']: [city['value'],
                                     self.count_real_distance(agent, agent.operator_center, city['coord'])]})
            elif city['flag'] == -1:
                blank_cities.update(
                    {city['coord']: [city['value'],
                                     self.count_real_distance(agent, agent.operator_center, city['coord'])]})
            elif city['flag'] == agent.color:
                our_cities.update(
                    {city['coord']: [city['value'],
                                     self.count_real_distance(agent, agent.operator_center, city['coord'])]})
        for city in agent.observation['cities']:  # 敌方算子遍历
            city_coord = city['coord']
            i = 0
            for operator in agent.observation['operators'] + agent.observation['passengers']:
                if operator['color'] != agent.color and agent.map.get_distance(operator['cur_hex'], city_coord) < 4:
                    if operator['sub_type'] == BopSubType.Tank:
                        if operator['blood'] == operator['max_blood']:
                            i += 10
                        else:
                            i += 10 * (1 - (0.1 * (2 ^ (4 - operator['blood']))))
                    elif operator['sub_type'] == BopSubType.IFV:
                        if operator['blood'] == operator['max_blood']:
                            i += 6
                        else:
                            i += 6 * (1 - (0.1 * (2 ^ (4 - operator['blood']))))
                    elif operator['sub_type'] == BopSubType.UGV:
                        if operator['blood'] == operator['max_blood']:
                            i += 5
                        else:
                            i += 5 * (1 - (0.1 * (2 ^ (4 - operator['blood']))))
                    elif operator['sub_type'] == BopSubType.Infantry:
                        if operator['blood'] == operator['max_blood']:
                            i += 6
                        else:
                            i += 6 * (1 - (0.1 * (2 ^ (4 - operator['blood']))))
                    elif operator['sub_type'] == BopSubType.CruiseMissle:
                        if operator['blood'] == operator['max_blood']:
                            i += 2
                        else:
                            i += 2 * (1 - (0.1 * (2 ^ (4 - operator['blood']))))
            if city_coord in blank_cities.keys():
                blank_cities[city_coord].append(i)
            elif city_coord in enemy_cities.keys():
                enemy_cities[city_coord].append(i)
            elif city_coord in our_cities.keys():
                our_cities[city_coord].append(i)
        standby_dict = deepcopy(blank_cities)
        standby_dict.update(enemy_cities)
        standby_dict.update(our_cities)
        for city_coord, scores in standby_dict.items():  # 夺控点分数计算：分值/（距离+敌方兵力）
            cities_scores.update({city_coord: 1 / (scores[1] + scores[2])})
        standby_list = []
        for scores in cities_scores.values():
            standby_list.append(scores)
        for city_coord, score in cities_scores.items():  # 夺控点权重（归一化）： 分数/sum（所有的分数）
            cities_weight.update({city_coord: round(score / sum(standby_list), 3)})

        def set_rank(a_dict):  # 字典根据value从高到低排序
            a_sort_list = sorted(a_dict.items(), key=lambda x: x[1], reverse=True)
            a_sort_dict = {}
            for n, s in a_sort_list:
                a_sort_dict[n] = s
            return a_sort_dict

        cities_weight_rank = set_rank(cities_weight)
        attack_cities = []
        defense_cities = []
        if blank_cities:
            attack_cities = [city for city in blank_cities]
        if enemy_cities:
            attack_cities += [city for city in enemy_cities]
        if our_cities:
            defense_cities = [city for city in our_cities]
        if MIISON == 0:  # 根据大mission划定激进和保守打法的比例（6：4）
            full_attack = round(len(attack_cities) * 0.6)
            attack = len(attack_cities) - full_attack
            full_defense = round(len(defense_cities) * 0.6)
            defense = len(defense_cities) - full_defense
        else:
            attack = round(len(attack_cities) * 0.6)
            full_attack = len(attack_cities) - attack
            defense = round(len(defense_cities) * 0.6)
            full_defense = len(defense_cities) - defense
        attack_cities_weight = {}
        defense_cities_weight = {}
        for city_coord, weight in cities_weight_rank.items():
            if city_coord in attack_cities:
                attack_cities_weight.update({city_coord: weight})
            elif city_coord in defense_cities:
                defense_cities_weight.update({city_coord: weight})
        attack_cities_result = {}
        defense_cities_result = {}
        i = 0
        for city, weight in attack_cities_weight.items():  # 确定夺控点的行为方式
            if i < full_attack:
                attack_cities_result.update({city: [weight, 2]})
            else:
                attack_cities_result.update({city: [weight, 0]})
            i += 1
        i = 0
        for city, weight in defense_cities_weight.items():
            if i < full_defense:
                defense_cities_result.update({city: [weight, 3]})
            else:
                defense_cities_result.update({city: [weight, 1]})
            i += 1
        result = attack_cities_result
        result.update(defense_cities_result)
        cities_rank_mission = set_rank(result)
        return cities_rank_mission

    def change_union_again(self, agent, union, city_weight):
        """
        city_weight:dict 夺控点排序结果 {夺控点坐标：[权重,行为方式]}
        union:list  [
                        {'city':坐标1,'mission':0,'member':[[obj_id,be_tree],[obj_id,be_tree]]}...
                        {'city':坐标2,'mission':0,'member':[[obj_id,be_tree],[obj_id,be_tree]]}
                    ]
        输出:转移联盟后的结果集合[
                              [(夺控点1转移算子的所有集合)
                                {'city':坐标1,'mission':0,'member':[[obj_id,be_tree],[obj_id,be_tree]]}...
                                {'city':坐标1,'mission':0,'member':[[obj_id,be_tree],[obj_id,be_tree]]}
                              ],
                              [(夺控点2转移算子的所有集合)
                                {'city':坐标2,'mission':0,'member':[[obj_id,be_tree],[obj_id,be_tree]]}...
                                {'city':坐标2,'mission':0,'member':[[obj_id,be_tree],[obj_id,be_tree]]}
                              ],....
                            ]
        """
        # city_weight = {3427: [0.243, 0], 3529: [0.165, 1], 3632: [0.181, 2], 4129: [0.146, 3], 3730: [0.264, 0]}
        standby = deepcopy(union)
        for i in union:
            for city, lst in city_weight.items():
                if i['city'] == city:  # 提出行为方式 并判断
                    if lst[1] != i['mission']:
                        i['mission'] = lst[1]  # 根据夺控点排序的结果改变行为方式
        member_list = []  # 存放转移出联盟的算子
        member_attact = []  # [[1, 0],[2, 0],[3, 0],[4, 0]] # 测试用 # 存放转移出联盟的进攻性算子
        member_defence = []  # 存放转移出联盟防御性的算子
        union_remove = []
        for i in union:
            # union_remove = copy.deepcopy(self.union_1st)
            # if i['mission'] == 0 or i['mission'] == 2:  # 进攻的行为方式 保留进攻性算子
            #     a = copy.deepcopy(i)
            #     for member in i['member']:  # 时不时有问题
            #         obj_id = member[0]
            #         bop = agent.get_bop(obj_id)
            #         if bop['sub_type'] == 2 or bop['sub_type'] == 4:  # 如果是步兵 无人战车 移走
            #             member_list.append(member)
            #             member_defence.append(member)  # 添加到防御算子中
            #     self.defence_operator = member_defence  # 有问题放的位置不对
            #     if member_list:
            #         for member in member_list:
            #             a['member'].remove(member)  # 删除进攻中的防御性算子
            #         union_remove.append(a)
            #         member_list.clear()
            #     else:
            #         union_remove.append(a)
            member_list_1 = []
            if i['mission'] == 1 or i['mission'] == 3:  # 防御的行为方式 保留进攻性防御
                a = copy.deepcopy(i)
                for member in i['member']:
                    obj_id = member[0]
                    bop = agent.get_bop(obj_id)
                    if bop['sub_type'] == 0 or bop['sub_type'] == 1:  # 如果算子是坦克和战车 移走
                        # member_list_1.append(member)
                        member_attact.append(member)
                        a['member'].remove(member)
                union_remove.append(a)
                self.attact_operator = member_attact
                # if member_list_1:
                #     for member in member_list_1:
                #         a['member'].remove(member)
                #     union_remove.append(a)
                #     member_list_1.clear()
                # else:
                #     union_remove.append(a)
            else:
                union_remove.append(i)

        def operator_group(list1):
            """
              输入list
             算子组合函数
             输出所有的组合list
            """
            tuple_list = []
            for i in list1:
                new = tuple(i)
                tuple_list.append(new)  # 变成元组的形式
            group_result = []
            result_final = []
            result_single = []
            new_test = []
            # if len(tuple_list) < 3:
            #     for i in range(1, len(tuple_list)+1):
            #         group = list(itertools.combinations(tuple_list, i))  # 1个一组 2个一组 3个一组
            #         for j in group:
            #             list_j = list(j)
            #             group_result.append(list_j)
            # else:
            #     for i in range(3, len(tuple_list)+1):
            #         group = list(itertools.combinations(tuple_list, i))  # 1个一组 2个一组 3个一组
            #         for j in group:
            #             list_j = list(j)
            #             group_result.append(list_j)
            # for single in group_result:
            #     result_single.clear()
            #     for i in single:
            #         i_new = list(i)  # 把元祖变成列表形式 依次添加到联盟中
            #         result_single.append(i_new)
            #         a = copy.deepcopy(result_single)
            #     result_final.append(a)
            # *************************************************
            # if len(tuple_list) < 3:
            #     for i in range(1, len(tuple_list) + 1):
            #         group = list(itertools.combinations(tuple_list, i))  # 1个一组 2个一组 3个一组
            #         new_test.append(group)
            # else:
            #     for i in range(len(tuple_list) - 1, len(tuple_list) + 1):
            #         group = list(itertools.combinations(tuple_list, i))  # 如果列表中有7个算子 那么结果为7个一组 6个一组
            #         new_test.append(group)  #new_test[[((),(),())],[]]
            # for i_list in new_test:
            #     for j_tuple in i_list:
            #         result_single.clear()
            #         single_tuple = list(j_tuple)
            #         a = copy.deepcopy(single_tuple)
            #         result_final.append(a)
            # *************************************************
            if len(tuple_list) < 3:
                for i in range(1, len(tuple_list) + 1):
                    group = list(itertools.combinations(tuple_list, i))  # 1个一组 2个一组 3个一组
                    for j in group:
                        list_j = list(j)
                        group_result.append(list_j)
            else:
                for i in range(len(tuple_list) - 1, len(tuple_list) + 1):
                    group = list(itertools.combinations(tuple_list, i))  # 如果列表中有7个算子 那么结果为7个一组 6个一组
                    for j in group:
                        list_j = list(j)
                        group_result.append(list_j)
            for single in group_result:
                result_single.clear()
                for i in single:
                    i_new = list(i)  # 把元祖变成列表形式 依次添加到联盟中
                    result_single.append(i_new)
                    a = copy.deepcopy(result_single)
                result_final.append(a)

            return result_final

        union_attact = []  #
        result = []
        result_attact = []
        for i in union_remove:
            remove1_time = time.time()
            if i['mission'] == 0 or i['mission'] == 2:  # 进攻的行为方式
                if member_attact:
                    a = copy.deepcopy(i)  # 深拷贝i 删除算子用
                    union_attact.append(i)
                    result.clear()
                    attact_group = operator_group(member_attact)
                    for group in attact_group:
                        for member in group:  # 依次向联盟中加入进攻行算子 比较效能值
                            a['member'].append(member)
                        b = copy.deepcopy(a)
                        result.append(b)
                        for member in group:  # 把添加的算子删除 恢复原样 便于添加新的算子组合
                            a['member'].remove(member)
                    c = copy.deepcopy(result)
                    result_attact.append(c)
                    # result.append(c)
                    # print(result)
                else:  # 没有进攻算子直接输出小联盟
                    result_attact.append([[i]])
            else:
                result_attact.append([[i]])
            remove2_time = time.time()
            # print('↓算子组合time↓')
            # print(remove2_time-remove1_time)
            # print(result_attact)
            # else:  # 防御的行为方式,保留防御算子
            #     a = copy.deepcopy(i)
            #     result.clear()
            #     if member_defence:
            #         defence_group = operator_group(member_defence)
            #         for group in defence_group:
            #             for member in group:
            #                 a['member'].append(member)
            #             b = copy.deepcopy(a)
            #             result.append([b])
            #             for member in group:
            #                 a['member'].remove(member)
            #         c = copy.deepcopy(result)
            #     else:
            #         new = copy.deepcopy(i)
            #         c = [[new]]
            #     result_attact.append(c)
        union_city_member = {}
        for union_one in standby:
            member_list = []
            for member in union_one['member']:
                member_list.append(member[0])
            union_city_member.update({union_one['city']: member_list})
        for i in result_attact:
            for union_one in i:
                if isinstance(union_one, list) == True:  # 如果输入的数据类型是列
                    union_2 = union_one[0]
                    cost_list = []
                    for member in union_2['member']:
                        for city, members in union_city_member.items():
                            if member[0] in members and city != union_2['city']:
                                for union_two in standby:
                                    if union_two['city'] == city:
                                        union_1 = union_two
                                        cost = self.create_cost(agent, member[0], union_1, union_2)
                                        cost_list.append(cost)
                    if cost_list:
                        union_one[0].update({'cost': max(cost_list)})
                else:
                    union_2 = union_one
                    cost_list = []
                    for member in union_2['member']:
                        for city, members in union_city_member.items():
                            if member[0] in members and city != union_2['city']:
                                for union_two in standby:
                                    if union_two['city'] == city:
                                        union_1 = union_two
                                        cost = self.create_cost(agent, member[0], union_1, union_2)
                                        cost_list.append(cost)
                    if cost_list:
                        union_one.update({'cost': max(cost_list)})

        return result_attact

    def group_three_cal(self, list_f):  # 三个算子一组的效能计算
        cal_list = []
        count_result = 0

        if self.mission in self.efficiency and self.mission in self.addition:  # 存储当前mission对应下的效能值和加成值
            efficiency = self.efficiency[self.mission]
            addition = self.addition[self.mission]
        else:
            return 0

        group = list(itertools.combinations(list_f, 2))  # 两个算子一组
        for i in group:
            lst = copy.deepcopy(list(list_f))
            for j in lst:
                if j in lst:
                    lst.remove(j)
            single = lst[0]  # 提取单个的元素
            cal_single = efficiency.get(single)
            if cal_single:
                count_result += cal_single
            cal_group = addition.get(i)
            if cal_group:
                cal_increment = 2 * cal_group  # 协同增量 = 0.25*
                count_result += cal_increment
                count_result += cal_group
            else:
                new_group = list(i)  # 反转组合 找
                new_group.reverse()
                new = tuple(new_group)
                cal_group_new = addition.get(new)
                if cal_group_new:
                    cal_increment = 2 * cal_group_new  # 协同增量 = 0.25*
                    count_result += cal_increment
                    count_result += cal_group_new

            cal_list.append(count_result)
        calculation = max(cal_list)
        return calculation

    def three_calculate_return(self, agent, task, mission):
        """
        计算期望回报函数（三个一组）
        param： task 一种任务分配的情况
        return： int 此种分配下的回报值
        mission
        """

        group_standby = []
        alliance = []
        alliance_value = {}
        alliance_result = {}
        scheme_value = 0
        value_dict = {}
        value_sort = {}
        if mission in self.efficiency and mission in self.addition:  # 存储当前mission对应下的效能值和加成值
            efficiency = self.efficiency[mission]
            addition = self.addition[mission]
        else:
            return 0

        def set_rank(a_dict):
            global value_sort
            a_sort_list = sorted(a_dict.items(), key=lambda x: x[1], reverse=True)
            a_sort_dict = {}
            for n, s in a_sort_list:
                a_sort_dict[n] = s
            return a_sort_dict

        for obj_id, obj_task in task.items():
            bop = agent.get_bop(obj_id)
            if bop:
                group_standby.append((bop['sub_type'], obj_task))
            else:
                return 0

        group = list(itertools.combinations(group_standby, 3))
        for group_single in group:
            value = self.group_three_cal(group_single)
            if value:
                value_dict.update({group_single: value})
        if value_dict:
            value_sort = set_rank(value_dict)
        standby = copy.deepcopy(group_standby)
        for value_single, value in value_sort.items():
            alliance_0 = value_single[0]
            alliance_1 = value_single[1]
            alliance_2 = value_single[2]
            if alliance_0 in standby:
                standby.remove(alliance_0)
                if alliance_1 in standby:
                    standby.remove(alliance_1)
                    if alliance_2 in standby:
                        alliance_result.update({value_single: value})
                        standby.remove(alliance_2)
                    else:
                        standby.append(alliance_1)
                        standby.append(alliance_0)
                else:
                    standby.append(alliance_0)
            else:
                break
        for efficiency_single in standby:
            if efficiency_single in efficiency.keys():
                scheme_value += efficiency[efficiency_single]
        for alliance_single, value in alliance_result.items():
            scheme_value += value
        return scheme_value

    def calculate_return(self, agent, task, mission):
        """
        计算期望回报函数（两个一组）
        param： task 一种任务分配的情况
        return： int 此种分配下的回报值
        mission
        """
        group_standby = []
        alliance = []
        alliance_value = {}
        alliance_result = []
        scheme_value = 0
        if mission in self.efficiency and mission in self.addition:  # 存储当前mission对应下的效能值和加成值
            efficiency = self.efficiency[mission]
            addition = self.addition[mission]
        else:
            return 0
        # enemy_situation = self.forecast_enemy_situation()
        # result = self.success_rate(task, enemy_situation) + self.operators_loss_rate(task, enemy_situation) + \
        #         self.destroy_enemy_score(task, enemy_situation)
        for obj_id, obj_task in task.items():
            bop = agent.get_bop(obj_id)
            if bop:
                group_standby.append((bop['sub_type'], obj_task))
            else:
                return 0
        group = list(itertools.combinations(group_standby, 2))
        for group_single in group:
            for i in addition:
                if (group_single[0] in i) and (group_single[1] in i):
                    alliance.append(group_single)
                else:
                    continue
        for alliance_single in alliance:
            for i in addition:
                if (alliance_single[0] in i) and (alliance_single[1] in i):
                    if addition.get(alliance_single):
                        alliance_value.update({alliance_single: addition[i]})
                        # {alliance_single: addition[i] * (efficiency[alliance_single[0][0]][alliance_single[0][1]] +
                        #                                  efficiency[alliance_single[1][0]][alliance_single[1][1]])})
                else:
                    continue

        def set_rank(a_dict):
            a_sort_list = sorted(a_dict.items(), key=lambda x: x[1], reverse=True)
            a_sort_dict = {}
            for n, s in a_sort_list:
                a_sort_dict[n] = s
            return a_sort_dict

        alliance_sort = set_rank(alliance_value)
        standby = copy.deepcopy(group_standby)
        for alliance_single in alliance_sort.keys():
            alliance_0 = alliance_single[0]
            alliance_1 = alliance_single[1]
            if alliance_0 in standby:
                standby.remove(alliance_0)
                if alliance_1 in standby:
                    alliance_result.append(alliance_single)
                    standby.remove(alliance_1)
                else:
                    standby.append(alliance_0)
            else:
                break
        for efficiency_single in standby:
            if efficiency_single in efficiency.keys():
                scheme_value += efficiency[efficiency_single]
        for alliance_single in alliance_result:
            for i in addition:
                if (alliance_single[0] in i) and (alliance_single[1] in i):
                    scheme_value += addition[i]
                    break
                else:
                    continue
        return scheme_value

    def add_calculate(self, agent, union):  # union改一下
        """
        计算关联指标的函数
        param： union 一种联盟分配的情况 list[{'city':,'mission':,'member':[[26,0],[27,0],[29,1]]},{'city':,'mission':,'member':[[26,0],[27,0],[29,1]]}]
        return： int 此种分配下的回报值
        """
        cost = None
        lst = {}
        task = {}
        tuplee_list = []
        count_result = 0
        if isinstance(union, list) == True:  # 如果输入的数据类型是列表
            mission = union[0]['mission']
            city_hex = union[0]['city']
            if 'cost' in union[0].keys():
                cost = union[0]['cost']
            for i in union[0]['member']:
                obj_id = i[0]
                betree = i[1]
                bop = agent.get_bop(obj_id)
                if bop:
                    subtype = bop['sub_type']
                    a = tuple([subtype, betree])
                    lst.update({obj_id: a})
        else:  # 不是则为字典格式
            mission = union['mission']
            city_hex = union['city']
            if 'cost' in union.keys():
                cost = union['cost']
            for i in union['member']:
                if i:
                    obj_id = i[0]
                    betree = i[1]
                    bop = agent.get_bop(obj_id)
                    if bop:
                        subtype = bop['sub_type']
                        a = tuple([subtype, betree])
                        lst.update({obj_id: a})
            # else:
            #     print(1)
        value_list = []
        # for i in union:
        #     for obj_id, betree in i['member']:
        #         bop = agent.get_bop(obj_id)
        #         if bop:
        #             subtype = bop['sub_type']
        #             a = tuple([subtype, betree])
        #             lst.update({obj_id: a})
        #     if len(lst)> 3:
        #         for obj_id, tuplee in lst.items():
        #             task.update({obj_id: tuplee[1]})# 先变成task的形式放在两个一组函数中
        #             tuplee_list.append(tuplee)  # 为了放在三个一组函数里面用
        #         count_result_2 = self.calculate_return(agent, task, mission)
        #         count_result_3 = self.three_calculate_return(agent, task, mission)  # 三个一组
        #         if count_result_3 > count_result_2:
        #             count_result = round(count_result_3, 4)
        #         else:
        #             count_result = round(count_result_2, 4)
        #         value_list.append(count_result)
        #     b = value_list.index(max(value_list))
        #     union_result = union[b]
        #     value = value_list[b]
        #     print()
        city_rank = self.rank_cities(agent, mission)
        if city_rank:
            if city_hex in city_rank.keys():
                weight = city_rank[city_hex][0]
        else:
            weight = 1
        if len(lst) == 1:
            for i in range(len(lst)):
                for obj_id, tuplee in lst.items():
                    calculation = self.efficiency[mission].get(tuplee)
                    if calculation:
                        count_result += calculation
        elif len(lst) == 2:
            for i in range(len(lst)):
                for obj_id, tuplee in lst.items():
                    task.update({obj_id: tuplee[1]})
            count_result += self.calculate_return(agent, task, mission)
        elif len(lst) > 2:
            for obj_id, tuplee in lst.items():
                task.update({obj_id: tuplee[1]})  # 先变成task的形式放在两个一组函数中
                tuplee_list.append(tuplee)  # 为了放在三个一组函数里面用
            count_result_2 = self.calculate_return(agent, task, mission)
            count_result_3 = self.three_calculate_return(agent, task, mission)  # 三个一组
            if count_result_3 > count_result_2:
                if cost:
                    count_result = round(count_result_3, 4) * weight * 100 / cost
                else:
                    count_result = round(count_result_3, 4) * weight
            else:
                if cost:
                    count_result = round(count_result_2, 4) * weight * 100 / cost
                else:
                    count_result = round(count_result_2, 4) * weight
        else:
            count_result = 0
        return count_result

    def choose_max_union(self, agent, result_list):  # 选择效能值最大的联盟
        """
        result_list:[
               [
                [{'city':夺控点1,'mission':2,'member':[obj_id,betree],[obj_id,betree]}], [{['city':夺控点1,'mission':2,'member':[obj_id,betree],[obj_id,betree]]}
                ],
               [
                [{'city':夺控点2,'mission':2,'member':[obj_id,betree],[obj_id,betree]],[['city':夺控点2,'mission':2,'member':[obj_id,betree],[obj_id,betree]}
                ]
             ]
        输出：list：[
                    [{'city':夺控点1,}], [{'city':夺控点2,}], [{'city':夺控点3,}]
                ]
        """
        value_list = []
        result = []

        # result = result_list
        for city_union in result_list:
            if len(city_union) == 1:
                result.append(city_union[0])
            else:
                value_list.clear()
                for single in city_union:
                    value = self.add_calculate(agent, single)
                    value_list.append(value)
                b = value_list.index(max(value_list))
                single_result = city_union[b]
                result.append(single_result)
            # print(result)
        return result

    def choose_union_operator(self, agent, list_union):
        """
        联盟选择最终的成员
        输入：list1 [
                        [{'city'：夺控点1,}], [{'city'：夺控点2,}], [{'city'：夺控点2,}]...
                    ]
        输出：list [
                         [{'city'：夺控点1,}], [{'city'：夺控点2,}], [{'city'：夺控点2,}]...
                    ]
        """
        if agent.observation['time']['cur_step'] > 320:
            print(1)
        union_attact = []  # 存放进攻联盟
        union_defence = []  # 存放防御联盟
        middle_list = []
        result_list = []

        final_result = []
        for i in list_union:
            if isinstance(i, list) != True:  # 如果输入的数据类型是
                if i['mission'] == 0 or i['mission'] == 2:
                    union_attact.append(i)
                else:
                    union_defence.append(i)
            else:
                for union in i:
                    if isinstance(union, list) != True:  # 如果输入的数据类型是字典
                        if union['mission'] == 0 or union['mission'] == 2:  # 行为方式是进攻的联盟放到一起
                            union_attact.append(union)
                        if union['mission'] == 1 or union['mission'] == 3:  # 行为方式是防守的联盟放到一起
                            union_defence.append(union)
                    else:
                        if union[0]['mission'] == 0 or union[0]['mission'] == 2:  # 行为方式是进攻的联盟放到一起
                            union_attact.append(union)
                        if union[0]['mission'] == 1 or union[0]['mission'] == 3:  # 行为方式是防守的联盟放到一起
                            union_defence.append(union)

        result = []
        union_delete = []  #
        attact_result = []
        if union_attact:
            if self.attact_operator:
                if len(union_attact) == 1:
                    union_delete = union_attact
                else:
                    middle_list_new = copy.deepcopy(union_attact)
                    tuple_list = []
                    tuple_result = []
                    for single in middle_list_new:
                        tuple_list.clear()
                        for member in single['member']:
                            member_tuple = tuple(member)  # 把联盟中的member变成元祖格式放到集合中
                            tuple_list.append(member_tuple)
                        a = copy.deepcopy(tuple_list)
                        tuple_result += a  # tuple_result: [  [],[],[]  ]
                    result_tuple = Counter(tuple_result)  # 用counter函数计算重复次数
                    sorted_list = sorted(result_tuple.items(), key=lambda x: x[1])
                    for i in sorted_list:
                        if i[1] > 1:  # 出现此处大于1 就说明重复了
                            result.append(i[0])
                    if result:
                        copy_attact = copy.deepcopy(self.attact_operator)
                        copy_result = copy.deepcopy(result)
                        union_attact_standby = copy.deepcopy(union_attact)
                        copy_attact_list = []
                        for i in copy_result:
                            i_list = list(i)
                            result_list.append(i_list)  # 变成列表形式 以便后续删除重复算子 少一个集合是空集的情况
                        for i in copy_attact:
                            i_tuple = tuple(i)
                            copy_attact_list.append(i_tuple)
                        if len(set(copy_attact_list) - set(result)):
                            member_leave = []
                            for j in self.attact_operator:  # 找result中没有的进攻算子 放到member_leave中 self_a_o [1,2,3]
                                if j not in result_list:  # result [1,3]
                                    member_leave.append(j)  # member_leave [2]
                            if member_leave:  # 判断是加入了联盟1 次 还是根本没有加入任意的联盟中
                                record = []
                                for i in union_attact:
                                    for member in i['member']:
                                        if member in member_leave:
                                            record.append(member)
                                if not record:
                                    for member in member_leave:
                                        union = random.choice(union_attact)
                                        union['member'].append(member)
                        while 1:
                            if result_list:
                                max_member_record = []  # 记录maxi联盟中在result中的member
                                valuelist = [self.add_calculate(agent, i) for i in
                                             union_attact_standby]  # 列表生成式计算每一个联盟的效能值
                                b = valuelist.index(max(valuelist))  # 找出最大的联盟
                                maxi = union_attact_standby[b]
                                # print(result_list)
                                for member in maxi['member']:
                                    if member in result_list:  # 找maxi中有几个result  self.att = [1,2,3]
                                        max_member_record.append(member)  # member_record = [1,3]
                                        result_list.remove(member)  # copy_result = [2]\
                                if max_member_record:
                                    union_delete.append(maxi)
                                    union_attact_standby.remove(maxi)
                                    for i in union_attact_standby:  # 删掉其他union中所有的1,3
                                        if i['city'] != maxi['city']:
                                            for member in max_member_record:
                                                if member in i['member']:
                                                    i['member'].remove(member)
                                        else:
                                            continue
                                else:
                                    union_delete.append(maxi)
                                    union_attact_standby.remove(maxi)
                                    continue
                            else:
                                break
                        union_delete = union_delete + union_attact_standby
                    else:
                        union_delete = union_attact
            else:
                union_delete = union_attact
        else:
            union_delete = union_attact
        if union_defence:
            for i in union_defence:
                union_delete.append(i)
        final_result = union_delete
        empty_union = []  # [{'city':,'member':,}]
        for i in range(len(final_result)):
            # for i in middle_list_new:
            if len(final_result[i]['member']) == 0:  # 没有算子
                empty_union.append(final_result[i])  # 没有基本兵力的算子存在empty中
        self.empty_union = empty_union
        # print(final_result)
        return final_result
        # def operator_delete(agent, union_list):
        #     """
        #     删除联盟中重复的元素
        #     输入：
        #            [{'city':,'mission':,'member':[[obj_id,betree],[obj_id,betree]]}],
        #            {}...
        #            ]
        #
        #     输出 :[
        #             {'city':,'mission':,'member':[[obj_id,betree],[obj_id,betree]]},
        #             {}...
        #          ](初始版本)
        #     """
        #     result = []
        #     union_delete = []
        #     if union_list:
        #         # middle_list.clear()
        #         # for union in union_list:
        #         #     a = copy.deepcopy(union)
        #             # for single in union['member']:
        #             #     if single[0] in self.paobing:  # 删除炮兵等独立联盟的算子
        #             #         a['member'].remove(single)
        #             #     if single[0] in self.uav:  # 删除无人机等独立联盟的算子
        #             #         a['member'].remove(single)
        #             #     if single[0] in self.cruise:  # 删除巡飞弹等独立联盟的算子
        #             #         a['member'].remove(single)
        #         #     middle_list.append(a)
        #         # middle_list_new = copy.deepcopy(middle_list)
        #         middle_list_new = copy.deepcopy(union_list)
        #     else:
        #         return None  # 列表是空的则返回None 退出函数
        #     # print(middle_list)
        #     # 遍历 微调 确保每个联盟的基本兵力
        #
        #     # print(empty_union)
        #     tuple_list = []
        #     tuple_result = []
        #     if len(union_list) == 1:
        #         union_delete = union_list
        #     else:
        #         for single in middle_list_new:
        #             tuple_list.clear()
        #             for member in single['member']:
        #                 member_tuple = tuple(member)  # 把联盟中的member变成元祖格式放到集合中
        #                 tuple_list.append(member_tuple)
        #             a = copy.deepcopy(tuple_list)
        #             tuple_result += a  # tuple_result: [  [],[],[]  ]
        #         result_tuple = Counter(tuple_result)  # 用counter函数计算重复次数
        #         sorted_list = sorted(result_tuple.items(), key=lambda x: x[1])
        #         for i in sorted_list:
        #             if i[1] > 1:  # 出现此处大于1 就说明重复了
        #                 result.append(i[0])
        #         if result:
        #             for i in result:
        #                 i_list = list(i)
        #                 result_list.append(i_list)  # 变成列表形式 以便后续删除重复算子 少一个集合是空集的情况
        #             copy_attact = copy.deepcopy(self.attact_operator)
        #             while 1:
        #                 if copy_attact :
        #                     valuelist = [self.add_calculate(agent, i) for i in union_list]  # 列表生成式计算每一个联盟的效能值
        #                     b = valuelist.index(max(valuelist))  # 找出最大的联盟
        #                     maxi = union_list[b]
        #                     member_leave = []
        #                     for j in self.attact_operator:
        #                         if j not in result_list:
        #                             member_leave.append(j)
        #                     for member in maxi['member']:
        #                         if member in self.attact_operator:
        #                             copy_attact.remove(member)
        #                     # for member in result_list:
        #                     #     if member not in maxi['member']:
        #                     #         member_leave.append(member)
        #                     self.max_union = maxi
        #                     for i in union_list:
        #                         i_copy = copy.deepcopy(i)
        #                         if i['city'] != maxi['city']:
        #                             for member in i['member']:
        #                                 if member in result_list:
        #                                     i_copy['member'].remove(member)
        #                             union_delete.append(i_copy)
        #                         else:
        #                             union_delete.append(i_copy)
        #                     if member_leave:  #
        #                         record = []
        #                         for i in union_delete:
        #                             for member in i['member']:
        #                                 if member in member_leave:
        #                                     record.append(member)
        #                         if record:
        #                             union_list = union_delete
        #                         else:
        #                             for i in union_delete:
        #                                 if i['city'] != maxi['city']:
        #                                     for member in member_leave:
        #                                         i['member'].append(member)
        #                                         break
        #                             union_list = union_delete
        #                     else:
        #                         union_list = union_delete
        #                 else:
        #                     break
        #         else:  # 空集情况下 直接输出原union
        #             for union in union_list:
        #                 union_delete.append(union)
        #     return union_delete

        # attact_result  =[]
        # if union_attact:
        #     if self.attact_operator:
        #         if len(union_attact) == 1:
        #             attact_result = union_attact
        #         else:
        #             # 提出maxi中坦克的坐标\
        #             attact_copy = copy.deepcopy(self.attact_operator)
        #             while 1:
        #                 if attact_copy:
        #                     add_list = []
        #                     valuelist = [self.add_calculate(agent, j) for j in union_attact]  # 列表生成式计算每一个联盟的效能值
        #                     b = valuelist.index(max(valuelist))  # 找出最大的联盟
        #                     maxi = union_attact[b]
        #                     for member in maxi['member']:
        #                         if member in self.attact_operator:
        #                             attact_copy.remove(member)
        #                             add_list.append(member)  # 找到max中添加到的进攻算子
        #                     self.max_union = maxi
        #                     for i in union_attact:
        #                         i_copy = copy.deepcopy(i)
        #                         if i['city']!= maxi['city']:
        #                             for member in i['member']:
        #                                 if member in add_list:
        #                                     i_copy['member'].remove(member)
        #                             attact_result.append(i_copy)
        #                         else:
        #                             attact_result.append(i_copy)
        #                     union_attact = attact_result
        #                 else:
        #                     break
        #     else:
        #         attact_result = union_attact
        #
        # if union_defence:
        #     for i in union_defence:
        #         attact_result.append(i)
        # empty_union = []  # [{'city':,'member':,}]
        # for i in range(len(attact_result)):
        #     # for i in middle_list_new:
        #     if len(attact_result[i]['member']) == 0:  # 没有算子
        #         empty_union.append(attact_result[i])  # 没有基本兵力的算子存在empty中
        # self.empty_union = empty_union
        # return attact_result

        '''
        result = []
        union_delete = []
        attact_result  =[]
        if union_attact:
            if self.attact_operator:
                if len(union_attact) == 1:
                    union_delete= union_attact
                else:
                    middle_list_new = copy.deepcopy(union_attact)
                    tuple_list = []
                    tuple_result = []
                    for single in middle_list_new:
                        tuple_list.clear()
                        for member in single['member']:
                            member_tuple = tuple(member)  # 把联盟中的member变成元祖格式放到集合中
                            tuple_list.append(member_tuple)
                        a = copy.deepcopy(tuple_list)
                        tuple_result += a  # tuple_result: [  [],[],[]  ]
                    result_tuple = Counter(tuple_result)  # 用counter函数计算重复次数
                    sorted_list = sorted(result_tuple.items(), key=lambda x: x[1])
                    for i in sorted_list:
                        if i[1] > 1:  # 出现此处大于1 就说明重复了
                            result.append(i[0])
                    if result:
                        for i in result:
                            i_list = list(i)
                            result_list.append(i_list)  # 变成列表形式 以便后续删除重复算子 少一个集合是空集的情况
                        copy_attact = copy.deepcopy(self.attact_operator)
                        while 1:
                            if copy_attact:
                                valuelist = [self.add_calculate(agent, i) for i in union_attact]  # 列表生成式计算每一个联盟的效能值
                                b = valuelist.index(max(valuelist))  # 找出最大的联盟
                                maxi = union_attact[b]
                                member_leave = []
                                for j in self.attact_operator:
                                    if j not in result_list:
                                        member_leave.append(j)
                                for member in maxi['member']:
                                    if member in self.attact_operator:
                                        if member in copy_attact:
                                        #     print('member')
                                        #     print(member)
                                        #     print('self.attact_operator')
                                        #     print(self.attact_operator)
                                        #     print('copy_attact')
                                        #     print(copy_attact)
                                        # else:
                                            copy_attact.remove(member)
                                # for member in result_list:
                                #     if member not in maxi['member']:
                                #         member_leave.append(member)
                                self.max_union = maxi
                                for i in union_attact:
                                    i_copy = copy.deepcopy(i)
                                    if i['city'] != maxi['city']:
                                        for member in i['member']:
                                            if member in result_list:
                                                i_copy['member'].remove(member)
                                        union_delete.append(i_copy)
                                    else:
                                        union_delete.append(i_copy)
                                if member_leave:  #
                                    record = []
                                    for i in union_delete:
                                        for member in i['member']:
                                            if member in member_leave:
                                                record.append(member)
                                    if record:
                                        union_attact = union_delete
                                    else:
                                        for i in union_delete:
                                            if i['city'] != maxi['city']:
                                                for member in member_leave:
                                                    i['member'].append(member)
                                                    break
                                        union_attact = union_delete
                                else:
                                    union_attact = union_delete
                            else:
                                break
                    else:  # 空集情况下 直接输出原union
                        union_delete = union_attact
            else:
                union_delete = union_attact
        if union_defence:
            for i in union_defence:
                union_delete.append(i)
        '''

    def empty_change(self, agent, union_delete):  # 微调 保证联盟的基本兵力
        """
        2023.7.11
        union_delete 删除完重复算子的联盟:(dict)
                                  {
                                    0: [{'city':,'mission':'member':,}...]
                                    1: [{'city':,'mission':'member':,}]
                                   }
        输出 union_final(list)

        """
        union_set_defence = []  # 防御联盟集合
        union_set_attact = []  # 进攻联盟集合
        bubing_set_a = []  # 存放进攻联盟中的步兵obj_id

        for i in union_delete:
            if i['mission'] == 1 or i['mission'] == 3:
                union_set_defence.append(i)  # union_set_defence:防御联盟集合
            if i['mission'] == 0 or i['mission'] == 2:
                union_set_attact.append(i)  # union_set_attact:进攻联盟集合

        for empty_i in self.empty_union:
            tank_set = []
            for i in union_delete:  # 提出有坦克的联盟
                # 存放有tank的联盟
                for member in i['member']:
                    if member[0] in self.tank:
                        tank_set.append(i)
                        break
            if empty_i['mission'] == 1 or empty_i['mission'] == 3:  # 防御联盟bao zheng you bubing
                for i in union_delete:  # 5ge union
                    list_bubing_a = []
                    for member in i['member']:
                        if member[0] in self.bubing:
                            list_bubing_a.append(member)
                    bubing_set_a.append([i['city'], list_bubing_a])
                len_list_a = []
                for i in bubing_set_a:
                    len_list_a.append(len(i[1]))
                if len(len_list_a) != 0:
                    max_a = len_list_a.index(max(len_list_a))
                    distance_list_a = []
                    for i in bubing_set_a[max_a][1]:
                        obj_id = i[0]
                        bop = agent.get_bop(obj_id)
                        distance_list_a.append(agent.map.get_distance(bop['cur_hex'], empty_i['city']))
                    if distance_list_a:
                        b = distance_list_a.index(min(distance_list_a))  # 选出最近的步兵
                        bubing_choose = bubing_set_a[max_a][1][b]
                        final1 = []
                        for single in union_delete:
                            new_copy = copy.deepcopy(single)
                            if single['city'] == bubing_set_a[max_a][0]:
                                if bubing_choose in single['member']:
                                    new_copy['member'].remove(bubing_choose)  # 移除maxi中的坦克
                                    final1.append(new_copy)
                            elif single['city'] == empty_i['city']:
                                new_copy['member'].append(bubing_choose)  # 移除maxi中的坦克
                                final1.append(new_copy)
                            else:
                                final1.append(new_copy)
                        union_delete = final1

            else:  # 进攻
                # 在有坦克的联盟中遍历效能值 找到最大的
                tank_pos = []  # [[obj_id,cur_hex]] 存放坦克obj_id和当前坐标
                value_list_first = [self.add_calculate(agent, i) for i in tank_set]
                value_list = copy.deepcopy(value_list_first)
                if value_list:
                    b = value_list.index(max(value_list))
                    maxi = tank_set[b]  # 找出效能值最大的联盟
                    for member in maxi['member']:
                        if member[0] in self.tank:
                            obj_id = member[0]
                            bop = agent.get_bop(obj_id)
                            tank_pos.append([obj_id, bop['cur_hex'], bop['blood'], member[1]])  # obj_id 位置 血量
                    # 判断tank的数量
                    # if len(tank_pos) > 1:
                    distance_new = [agent.map.get_distance(empty_i['city'], i[1]) for i in tank_pos]
                    distance = copy.deepcopy(distance_new)
                    b = distance.index(min(distance))  # 选出距离该夺控点最近的坦克
                    choose_tank = [tank_pos[b][0], tank_pos[b][3]]  # 选出坦克[obj_id,betree]
                    final = []
                    for single in union_delete:
                        value_list_first.clear()
                        new_copy = copy.deepcopy(single)
                        if single['city'] == maxi['city']:
                            if choose_tank in single['member']:
                                new_copy['member'].remove(choose_tank)  # 移除maxi中的坦克
                                final.append(new_copy)
                            # else:  # tank被移走了？
                        elif single['city'] == empty_i['city']:  # 加入到空联盟中
                            new_copy['member'].append(choose_tank)
                            final.append(new_copy)
                        else:
                            final.append(new_copy)
                    distance_new.clear()
                    union_delete = final

                # else:  # 如果只有一个坦克
                #     pos_list = []  # 记录坦克坐标
                #     copy_remove = copy.deepcopy(tank_set)
                #     copy_remove.remove(maxi)  # 删掉最大的
                #     value_2 = [self.add_calculate(agent, i) for i in copy_remove]  # 再次遍历 找到第二大的
                #     value = copy.deepcopy(value_2)
                #     if value:
                #         b = value.index(max(value))
                #         max_union = copy_remove[b]
                #         for member in max_union['member']:  # 遍历第二大的联盟算子 找到联盟中最近的坦克
                #             if max_union['member']:
                #                 if member[0] in self.tank:
                #                     obj_id = member[0]
                #                     bop = agent.get_bop(obj_id)
                #                     pos_list.append([obj_id, bop['cur_hex'], bop['blood'], member[1]])
                #         distance = [agent.map.get_distance(empty_i['city'], i[1]) for i in pos_list]
                #         d = distance.index(min(distance))  # 找出距离该夺控点最近的
                #         choose_tank = [pos_list[d][0], pos_list[d][3]]  # 选出坦克
                #         value_2.clear()
                #         for single in union_delete:
                #             new_copy = copy.deepcopy(single)
                #             if single['city'] == max_union['city']:
                #                 if choose_tank in new_copy['member']:
                #                     new_copy['member'].remove(choose_tank)  # 移除maxi中的坦克
                #                     final.append(new_copy)
                #             elif single['city'] == empty_i['city']:
                #                 new_copy['member'].append(choose_tank)
                #                 final.append(new_copy)
                #             else:
                #                 final.append(new_copy)
                #     else:
                #         union_delete = final

        return union_delete

    def empty_union_change(self, agent, union_delete):  # 微调 保证联盟的基本兵力
        """
        union_delete 删除完重复算子的联盟:(dict)
                                  {
                                    0: [{'city':,'mission':'member':,}...]
                                    1: [{'city':,'mission':'member':,}]
                                   }
        输出 union_final(list)

        """
        union_final = []
        union_final1 = []
        final = []  # 存放最终结果
        final1 = []
        union_set = []
        union_set_defence = []
        bubing_set = []
        bubing_set_a = []
        choose_tank = None
        distance_list = []
        distance_list_a = []
        for i in union_delete:
            if i['mission'] == 1 or i['mission'] == 3:
                union_set_defence.append(i)  # union_set_defence:防御联盟集合
            if i['mission'] == 0 or i['mission'] == 2:
                union_set.append(i)  # union_set:进攻联盟集合

        for empty_i in self.empty_union:
            if empty_i['mission'] == 1 or empty_i['mission'] == 3:  # 防御联盟直接输出 不分配基本兵力
                if len(union_set_defence) == 1:  # 如果只有一个防御联盟 就说名步兵都存放在攻击联盟中
                    for i in union_set:
                        list_bubing_a = []
                        for member in i['member']:
                            if member[0] in self.bubing:
                                list_bubing_a.append(member)
                        bubing_set_a.append([i['city'], list_bubing_a])
                    len_list_a = []
                    for i in bubing_set_a:
                        len_list_a.append(len(i[1]))
                    if len(len_list_a) != 0:
                        max_a = len_list_a.index(max(len_list_a))
                        for i in bubing_set_a[max_a][1]:
                            obj_id = i[0]
                            bop = agent.get_bop(obj_id)
                            distance_list_a.append(agent.map.get_distance(bop['cur_hex'], empty_i['city']))
                        if distance_list_a:
                            b = distance_list_a.index(min(distance_list_a))  # 选出最近的步兵
                            bubing_choose = bubing_set_a[max_a][1][b]
                            empty_copy = copy.deepcopy(empty_i)
                            empty_copy['member'].append(bubing_choose)
                            final1.append(empty_copy)
                            for single in union_set:
                                new_copy = copy.deepcopy(single)
                                if single['city'] == bubing_set_a[max_a][0]:
                                    # if choose_tank not in single['member']:
                                    new_copy['member'].remove(bubing_choose)  # 移除maxi中的坦克
                                    final1.append(new_copy)
                                else:
                                    final1.append(new_copy)
                else:
                    for i in union_set_defence:
                        list_bubing = []
                        for member in i['member']:
                            if member[0] in self.bubing:
                                list_bubing.append(member)
                        bubing_set.append([i['city'], list_bubing])
                    len_list = []
                    for i in bubing_set:
                        len_list.append(len(i[1]))
                    if len(len_list) != 0:
                        max_a = len_list.index(max(len_list))
                        for i in bubing_set[max_a][1]:
                            obj_id = i[0]
                            bop = agent.get_bop(obj_id)
                            distance_list.append(agent.map.get_distance(bop['cur_hex'], empty_i['city']))
                        if distance_list:
                            b = distance_list.index(min(distance_list))  # 选出最近的步兵
                            bubing_choose = bubing_set[max_a][1][b]
                            for single in union_set_defence:
                                new_copy = copy.deepcopy(single)
                                if single['city'] == bubing_set[max_a][0]:
                                    # if choose_tank not in single['member']:
                                    new_copy['member'].remove(bubing_choose)  # 移除maxi中的坦克
                                    final1.append(new_copy)
                                elif single['city'] == empty_i['city']:  # 加入到空联盟中
                                    new_copy['member'].append(bubing_choose)
                                    final1.append(new_copy)
                                else:
                                    final1.append(new_copy)

                    union_final1 = final1
                    # if empty_i['city'] == i['city']:
                    #     union_final1.append(i)
            else:  # 进攻分配兵力

                tank_pos = []  # [[obj_id,cur_hex]] 存放坦克obj_id和当前坐标
                value_list_first = [self.add_calculate(agent, i) for i in union_set]
                value_list = copy.deepcopy(value_list_first)
                b = value_list.index(max(value_list))
                maxi = union_delete[b]  # 找出效能值最大的联盟
                for member in maxi['member']:
                    if member[0] in self.tank:
                        obj_id = member[0]
                        bop = agent.get_bop(obj_id)
                        tank_pos.append([obj_id, bop['cur_hex'], bop['blood'], member[1]])  # obj_id 位置 血量
                # 判断tank的数量
                if len(tank_pos) > 1:
                    distance = [agent.map.get_distance(empty_i['city'], i[1]) for i in tank_pos]
                    b = distance.index(min(distance))  # 选出距离该夺控点最近的坦克
                    choose_tank = [tank_pos[b][0], tank_pos[b][3]]  # 选出坦克[obj_id,betree]
                    for single in union_set:
                        value_list_first.clear()
                        new_copy = copy.deepcopy(single)
                        if single['city'] == maxi['city']:
                            if choose_tank in single['member']:
                                new_copy['member'].remove(choose_tank)  # 移除maxi中的坦克
                                final.append(new_copy)
                            # else:  # tank被移走了？
                        elif single['city'] == empty_i['city']:  # 加入到空联盟中
                            new_copy['member'].append(choose_tank)
                            final.append(new_copy)
                        else:
                            final.append(new_copy)
                else:  # 如果只有一个坦克
                    pos_list = []  # 记录坦克坐标
                    copy_remove = copy.deepcopy(union_set)
                    copy_remove.remove(maxi)  # 删掉最大的
                    value_2 = [self.add_calculate(agent, i) for i in copy_remove]  # 再次遍历 找到第二大的
                    value = copy.deepcopy(value_2)
                    b = value.index(max(value))
                    max_union = copy_remove[b]
                    for member in max_union['member']:  # 遍历第二大的联盟算子 找到联盟中最近的坦克
                        if max_union['member']:
                            if member[0] in self.tank:
                                obj_id = member[0]
                                bop = agent.get_bop(obj_id)
                                pos_list.append([obj_id, bop['cur_hex'], bop['blood'], member[1]])
                    distance = [agent.map.get_distance(empty_i['city'], i[1]) for i in pos_list]
                    d = distance.index(min(distance))  # 找出距离该夺控点最近的
                    choose_tank = [pos_list[d][0], pos_list[d][3]]  # 选出坦克
                    value_2.clear()
                    for single in union_set:
                        new_copy = copy.deepcopy(single)
                        if single['city'] == max_union['city']:
                            if choose_tank in new_copy['member']:
                                new_copy['member'].remove(choose_tank)  # 移除maxi中的坦克
                                final.append(new_copy)
                        elif single['city'] == empty_i['city']:
                            new_copy['member'].append(choose_tank)
                            final.append(new_copy)
                        else:
                            final.append(new_copy)

                union_set = final

        if final:
            for i in final:
                union_final1.append(i)
        if final1:
            for i in final1:
                union_final1.append(i)
        city_list = []
        if union_final1:
            for j in union_final1:
                city_list.append(j['city'])
            for i in range(len(union_delete)):
                if union_delete[i]['city'] not in city_list:
                    union_final1.append(union_delete[i])
            # for i in union_delete:
            #     for j in union_final1:
            #         if i['city'] != j['city']:
            #             if i not in union_final1:
            #                 union_final1.append(i)
        else:
            union_final1 = union_delete

        # union_final1.append(final)
        return union_final1

    def betree_change(self, agent, union_list1):
        """
        联盟中为转移的算子转移行为树
        输入：list
                 [
                            {'city':,'mission':,'member':[[obj_id,betree],[obj_id,betree]]},
                            {'city':,'mission':,'member':[[obj_id,betree],[obj_id,betree]]},...
                 ]
        输出：list
                    [
                        [{'city'：夺控点1,}], [{'city'：夺控点2,}], [{'city'：夺控点2,}]...
                    ]
        """

        def change_betree_number(union_dict1):
            """
            联盟中为转移的算子转移行为树
            输入dict：{'city':1,'mission':,'member':[[obj_id,betree],[obj_id,betree]]}
            输出：单个联盟中每个算子行为树改变的结果
            list：[
                        {'city':1,'mission':,'member':[[obj_id,betree],[obj_id,betree]]}
                        {'city':1,'mission':,'member':[[obj_id,betree],[obj_id,betree]]}
                        {'city':1,'mission':,'member':[[obj_id,betree],[obj_id,betree]]}...
                    ]
            """
            task_gather_1 = [0, 1, 2]
            result_list = []
            result = []
            dict1 = {}
            list1 = union_dict1['member']
            for j in range(len(list1)):
                a = copy.deepcopy(list1[j])
                if list1[j]:
                    task = list1[j][1]
                    task_gather = copy.deepcopy(task_gather_1)
                    task_gather.remove(task)  # 删除原有的行为 便于后续重新选择
                    for new in task_gather:
                        if isinstance(a, list) == True:
                            a[1] = new
                        else:
                            a = list(a)
                            a[1] = new
                        b = copy.deepcopy(a)
                        union3 = copy.deepcopy(list1)
                        union3.append(b)
                        union3.remove(list1[j])
                        result.append(union3)  # 结果
            for i in result:
                dict1.update({'city': union_dict1['city'], 'mission': union_dict1['mission'], 'member': i})
                a = copy.deepcopy(dict1)
                result_list.append(a)
            # print(result_list)
            return result_list

        union_set = []
        member_remove = {}
        member_delete_list = []
        for union_single in union_list1:
            if union_single['mission'] == 0 or union_single['mission'] == 2:  # 进攻集合
                list1 = []
                if self.attact_operator:
                    a = copy.deepcopy(union_single)
                    for member in union_single['member']:  # 遍历算子
                        if member in self.attact_operator:  # 如果算子在攻击算子中
                            list1.append(member)  # 添加算子
                            a['member'].remove(member)  # 移除算子
                    if list1:  # 把删除的算子存放起来 便于后续添加
                        a_new = copy.deepcopy(list1)
                        member_remove.update({union_single['city']: a_new})
                        b = copy.deepcopy(member_remove)
                        member_delete_list.append(b)
                        member_remove.clear()
                        union_set.append(a)  # 删除添加后的算子
                    else:  # 如果都不在
                        union_set.append(union_single)  # 不用删除直接添加
                else:  # 如果没有进攻算子 直接输出原联盟
                    union_set.append(union_single)
            else:  # 防御集合
                list2 = []
                if self.defence_operator:
                    a = copy.deepcopy(union_single)
                    for member in union_single['member']:
                        if member in self.defence_operator:  # 如果算子在防守算子中
                            list2.append(member)
                            a['member'].remove(member)
                    if list2:  # 把删除的算子存放起来 便于后续添加
                        a_new = copy.deepcopy(list2)
                        member_remove.update({union_single['city']: a_new})
                        b = copy.deepcopy(member_remove)
                        member_delete_list.append(b)
                        member_remove.clear()
                        union_set.append(a)  # 删除添加后完的算子联盟
                    else:  # 如果都不在
                        union_set.append(union_single)  # 不用删除直接添加
                else:  # 如果没有防御算子 直接输出原联盟
                    union_set.append(union_single)

        value_list = []
        add_standby = []
        final_result = []

        for single_union in union_set:  # 遍历每一个联盟
            value_list.clear()
            result_set = change_betree_number(single_union)
            if result_set:
                for i in result_set:
                    value = self.add_calculate(agent, i)
                    value_list.append(value)
                if value_list:
                    b = value_list.index(max(value_list))  # 找到效能值最大的行为树组合
                    single_result = result_set[b]
                    add_standby.append(single_result)
            else:
                add_standby.append(single_union)
        for i in add_standby:  # 遍历每个联盟 加入之前删除的算子
            if member_delete_list:  # 如果字典是空的 就说明没删除算子
                for j in member_delete_list:  # 判断该夺控点联盟是否删除算子
                    for coord, members in j.items():
                        if i['city'] == coord:  # 如果夺控点被记录
                            for member in members:
                                i['member'].append(member)  # 添加算子
                final_result.append(i)
                # else:  # 如果没被记录
                #     final_result.append(i)
            else:  # 没有删除算子
                final_result.append(i)  # 直接添加
        # print(final_result)
        return final_result

    def count_time(self, agent, obj_id, start_pos, target_pos):
        bop = agent.get_bop(obj_id)
        basic_speed = BasicSpeed.basic_speed[bop['sub_type']]
        move_time = 0
        pos_star = start_pos
        if bop['sub_type'] == BopSubType.Infantry:
            move_cost = agent.map.cost[MoveType.Walk]
            mode = MoveType.Walk
        elif bop['sub_type'] in [BopSubType.Drone, BopSubType.Helicopter, BopSubType.MineClearance,
                                 BopSubType.TransportHeli]:
            move_cost = agent.map.cost[MoveType.Fly]
            mode = MoveType.Fly
        elif bop['sub_type'] in [BopSubType.Tank, BopSubType.IFV, BopSubType.Artillery, BopSubType.UGV,
                                 BopSubType.ReconnaissanceVehicle, BopSubType.RadarVehicle, BopSubType.Minelayer,
                                 BopSubType.MineClearance, BopSubType.AntiAircraftGun, BopSubType.AntiAircraftPlatoon,
                                 BopSubType.AntiAircraftVehi, BopSubType.PickupTruck]:

            move_cost = agent.map.cost[MoveType.Maneuver]
            mode = MoveType.Maneuver
        else:
            return False
        route = agent.map.gen_move_route(start_pos, target_pos, mode)
        if route and move_cost and basic_speed:
            for pos_end in route[0]:
                cost = move_cost[pos_star // 100][pos_star % 100][pos_end]
                current_speed = basic_speed / cost
                pos_star = pos_end
                if current_speed:
                    move_time += current_speed
        else:
            return False
        if move_time:
            return move_time

    def create_cost(self, agent, obj_id, union_0, union_1):  # 代价计算函数  参与算子：坦克、战车、无人战车、步兵、直升机、侦察型战车(去掉了扫雷车）
        target_pos = None
        task = None
        union_1_times = []
        bop = agent.get_bop(obj_id)
        if bop['sub_type'] in [BopSubType.Tank, BopSubType.IFV, BopSubType.UGV, BopSubType.Infantry,
                               BopSubType.Helicopter,
                               BopSubType.ReconnaissanceVehicle]:
            for member in union_0['member']:
                if obj_id == member[0]:
                    task = member[1]
            if bop['sub_type'] == BopSubType.Tank:  # 坦克
                region = agent.map.get_neighbors(union_1['city'])
                region.append(union_1['city'])
                if task == 0:  # 进攻任务
                    target_pos = infer_tank_attack_pos(agent, obj_id, region, union_1['city'])
                elif task == 1:  # 防御任务
                    target_pos = Tank_defense_pos(agent, obj_id, region)
                else:  # 侦查任务
                    target_pos = union_1['city']
            elif bop['sub_type'] == BopSubType.IFV:  # 战车
                region = agent.map.get_neighbors(union_1['city'])
                region.append(union_1['city'])
                if task == 0:  # 进攻任务
                    target_pos = ifv_infer_attack_pos(agent, obj_id, region, union_1['city'])
                elif task == 1:  # 防御任务
                    target_pos = IFV_defense_pos(agent, obj_id, region)
                else:  # 侦查任务
                    target_pos = union_1['city']
            elif bop['sub_type'] == BopSubType.Infantry:  # 步兵
                if task == 0:  # 进攻任务
                    if bop['car']:
                        denfend_city_pos, target_pos, target_pos = infantry_attack_infer_coord(agent, bop['car'], None)
                    else:
                        denfend_city_pos, target_pos = infantry_attack_infer_coord_without_car(agent, obj_id, None)
                elif task == 1:  # 防御任务
                    if bop['car']:
                        denfend_city_pos, target_pos, target_pos = infantry_defence_infer_coord(agent, bop['car'], None)
                    else:
                        denfend_city_pos, target_pos, target_pos = infantry_defence_infer_coord_without_car(agent,
                                                                                                            obj_id,
                                                                                                            None)
            elif bop['sub_type'] == BopSubType.UGV:  # 无人战车
                target_pos = uv_infer_coord(agent, obj_id, union_1['city'])
            elif bop['sub_type'] == BopSubType.Helicopter:  # 直升机
                # 用第一个推理点位函数
                target_pos = Helicopter_infer_attack_pos(agent, obj_id, union_1['city'])
            elif bop['sub_type'] == BopSubType.ReconnaissanceVehicle:  # 侦查型战车
                target_pos = RV_infer_detect_pos(agent, obj_id, union_1['city'])
            else:
                return False
            if self.count_time(agent, obj_id, bop['cur_hex'], target_pos):
                time1 = self.count_time(agent, obj_id, bop['cur_hex'], target_pos)
            else:
                time1 = 0
            for member in union_1['member']:
                member_id = member[0]
                if member_id != obj_id:
                    member_bop = agent.get_bop(member_id)
                    if member_id in agent.target_pos.keys():
                        time = self.count_time(agent, member_id, member_bop['cur_hex'], agent.target_pos[member_id])
                        if time:
                            union_1_times.append(time)
                        else:
                            time2 = 0
                            break
                    else:
                        union_1_times.append(self.count_time(agent, member_id, member_bop['cur_hex'], union_1['city']))
            if union_1_times and union_1_times[0]:
                time2 = sum(union_1_times) / len(union_1_times)
            else:
                time2 = 0
            time_cost = math.fabs(time1 - time2)
            return time_cost
        else:
            return False

    def append_operator(self, agent):
        """
        根据夺控点排序情况调动算子 （无人机5 炮兵）
        无人机5
        """
        cities = self.cities
        num = []
        for i, j in self.rank_city_2.items():
            num.append(j[0])  # 提出概率

        def operator_add(num_list, list1):
            """
                每个算子分配一个夺控点 权重大的夺控点会分配到多个算子
                输入：每个夺控点的权重值 list
                输出：list [
                           [夺控点1,obj_id],[夺控点2,obj_id],...
                         ]
            """
            result0 = tuple(num_list)
            result = []
            city_standby = random.choices(cities, weights=result0, k=len(list1))
            for i in range(len(list1)):
                result.append([city_standby[i], list1[i]])
            return result

        if self.uav:
            uav_result = operator_add(num, self.uav)
        return uav_result

    def read(self, file):
        with open(file, "r") as csv_file:
            csv_reader = csv.reader(csv_file)

            efficiency_standby = {}
            addition_standby = {}
            for row, n in csv_reader:
                combination = []
                for i in row:
                    try:
                        b = int(i)
                        combination.append(b)
                    except:
                        continue
                if len(combination) == 2:
                    efficiency_standby.update({tuple(combination): float(n)})
                else:
                    standby = []
                    new_combination = []
                    for i in combination:
                        standby.append(i)
                        if len(standby) == 2:
                            new_combination.append(tuple(standby))
                            standby.clear()
                    addition_standby.update({tuple(new_combination): float(n)})
        return efficiency_standby, addition_standby
